<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" media="screen" href="/App_Themes/default/rss.xslt"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" 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:media="http://search.yahoo.com/mrss/" xmlns:evnet="http://www.mscommunities.com/rssmodule/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><channel><title>Entries tagged with asp.net - Channel 9</title><atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/tags/asp.net/feed/ipod/default.aspx" /><itunes:summary>asp.net</itunes:summary><itunes:author>Erik Porter, Charles, Mike Sampson, Grace Francisco, Brian Keller, Nathan Heskew, dshadle, Dan Fernandez, Duncan Mackenzie, Jeff Sandquist</itunes:author><itunes:subtitle></itunes:subtitle><image><url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url><title>Entries tagged with asp.net - Channel 9</title><link>http://channel9.msdn.com/tags/ASP.NET/</link></image><itunes:image href="http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png" /><itunes:category text="Technology" /><description>asp.net</description><link>http://channel9.msdn.com/tags/ASP.NET/</link><language>en-us</language><pubDate>Thu, 26 Nov 2009 13:58:52 GMT</pubDate><lastBuildDate>Thu, 26 Nov 2009 13:58:52 GMT</lastBuildDate><generator>EvNet (EvNet, Version=1.0.3608.3122, Culture=neutral, PublicKeyToken=null)</generator><item><title>ASP.NET Webcast Teil 4: Durchgaengiges Aussehen: Masterpages, Themes und Skins, Navigation</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_85_ch9.png" border="0" /&gt;Teil 4 der ASP.NET Webcast Serie: Durchgängiges Aussehen: Masterpages, Themes und Skins, Navigation&lt;br /&gt;
&lt;br /&gt;
Weitere auf http://webcast.codefest.at&lt;br /&gt;&lt;img src="http://channel9.msdn.com/509123/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-4-Durchgaengiges-Aussehen-Masterpages-Themes-und-Skins-Navigation/</comments><itunes:summary>Teil 4 der ASP.NET Webcast Serie: Durchgängiges Aussehen: Masterpages, Themes und Skins, Navigation

Weitere auf http://webcast.codefest.at</itunes:summary><link>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-4-Durchgaengiges-Aussehen-Masterpages-Themes-und-Skins-Navigation/</link><pubDate>Fri, 27 Nov 2009 10:57:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.mp4</guid><evnet:views>28</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/509123/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Teil 4 der ASP.NET Webcast Serie: Durchgängiges Aussehen: Masterpages, Themes und Skins, Navigation

Weitere auf http://webcast.codefest.at</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.mp4" expression="full" duration="3308" fileSize="172959524" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.mp3" expression="full" duration="3308" fileSize="26466044" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.mp4" expression="full" duration="3308" fileSize="172959524" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.wma" expression="full" duration="3308" fileSize="26764609" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.wmv" expression="full" duration="3308" fileSize="229779831" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_2MB_ch9.wmv" expression="full" duration="3308" fileSize="256377339" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_Zune_ch9.wmv" expression="full" duration="3308" fileSize="142915883" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_512_ch9.png" expression="full" duration="3308" type="image/jpeg" medium="image" /><media:content url="http://mschannel9.vo.msecnd.net/ss1/ch9/3/2/1/9/0/5/aspnet4.ism/Manifest" expression="full" duration="3308" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/3/2/1/9/0/5/aspnet4_ch9.mp4" length="172959524" type="video/mp4" /><dc:creator>codefest</dc:creator><itunes:author>codefest</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-4-Durchgaengiges-Aussehen-Masterpages-Themes-und-Skins-Navigation/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/509123/Trackback.aspx</trackback:ping><category>ASP.NET</category></item><item><title>ASP.NET Webcast Teil 3: Datenbankzugriff, Binden von Daten auf Control, Validierung</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_85_ch9.png" border="0" /&gt;Teil 3 der siebenteiligen Webcast Serie&lt;img src="http://channel9.msdn.com/507500/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-3-Datenbankzugriff-Binden-von-Daten-auf-Control-Validierung/</comments><itunes:summary>Teil 3 der siebenteiligen Webcast Serie</itunes:summary><link>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-3-Datenbankzugriff-Binden-von-Daten-auf-Control-Validierung/</link><pubDate>Thu, 19 Nov 2009 15:48:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.mp4</guid><evnet:views>1265</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/507500/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Teil 3 der siebenteiligen Webcast Serie</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.mp4" expression="full" duration="4081" fileSize="176633850" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.mp3" expression="full" duration="4081" fileSize="32652027" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.mp4" expression="full" duration="4081" fileSize="176633850" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.wma" expression="full" duration="4081" fileSize="33006915" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.wmv" expression="full" duration="4081" fileSize="242030661" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_2MB_ch9.wmv" expression="full" duration="4081" fileSize="355013983" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_Zune_ch9.wmv" expression="full" duration="4081" fileSize="152430713" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_512_ch9.png" expression="full" duration="4081" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/0/0/5/7/0/5/aspnet03.ism/Manifest" expression="full" duration="4081" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/0/0/5/7/0/5/aspnet03_ch9.mp4" length="176633850" type="video/mp4" /><dc:creator>codefest</dc:creator><itunes:author>codefest</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-3-Datenbankzugriff-Binden-von-Daten-auf-Control-Validierung/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/507500/Trackback.aspx</trackback:ping><category>ASP.NET</category></item><item><title>ASP.NET Webcast Teil 2: ASP.NET  Server Controls, Listen, Detailansichten, Controls, Session State</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_85_ch9.png" border="0" /&gt;Teil 2 der Webcast Serie zu ASP.NET.&lt;br /&gt;
Die Serie im Überblick auf &lt;a href="http://webcast.codefest.at/"&gt;webcast.codefest.at&lt;/a&gt;.&lt;img src="http://channel9.msdn.com/504630/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-2-ASPNET-Basisframework--bersicht-Webforms/</comments><itunes:summary>Teil 2 der Webcast Serie zu ASP.NET.
Die Serie im Überblick auf webcast.codefest.at.</itunes:summary><link>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-2-ASPNET-Basisframework--bersicht-Webforms/</link><pubDate>Fri, 06 Nov 2009 16:21:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.mp4</guid><evnet:views>2423</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/504630/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Teil 2 der Webcast Serie zu ASP.NET.
Die Serie im Überblick auf webcast.codefest.at.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.mp4" expression="full" duration="3949" fileSize="170309237" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.mp3" expression="full" duration="3949" fileSize="31596292" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.mp4" expression="full" duration="3949" fileSize="170309237" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.wma" expression="full" duration="3949" fileSize="31940501" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.wmv" expression="full" duration="3949" fileSize="227420819" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_2MB_ch9.wmv" expression="full" duration="3949" fileSize="317277191" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_Zune_ch9.wmv" expression="full" duration="3949" fileSize="146364871" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_512_ch9.png" expression="full" duration="3949" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/0/3/6/4/0/5/aspnet022009_ch9.mp4" length="170309237" type="video/mp4" /><dc:creator>codefest</dc:creator><itunes:author>codefest</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-2-ASPNET-Basisframework--bersicht-Webforms/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/504630/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Screencast</category><category>webcast</category><category>webforms</category></item><item><title>Introducción a ASP.NET AJAX</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_85_ch9.png" border="0" /&gt;Elisa García Anzano, Academic Developer Advisor en Microsoft Ibérica, nos hace una introducción a ASP.NET AJAX. Un webcast muy práctico en el que Elisa nos muestra las ventajas de usar AJAX, y nos comenta algunas otras cosas como el AJAX Control Toolkit y la librería jQuery.&lt;br /&gt;
&lt;br /&gt;
- Enlaces&lt;br /&gt;
&lt;a href="http://www.asp.net/ajax" target="_blank"&gt;http://www.asp.net/ajax&lt;br /&gt;
&lt;/a&gt;&lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples" target="_blank"&gt;http://www.asp.net/AJAX/AjaxControlToolkit/Samples&lt;/a&gt;&lt;br /&gt;&lt;img src="http://channel9.msdn.com/503738/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/channel9spain/Introduccin-a-ASPNET-AJAX/</comments><itunes:summary>Elisa García Anzano, Academic Developer Advisor en Microsoft Ibérica, nos hace una introducción a ASP.NET AJAX. Un webcast muy práctico en el que Elisa nos muestra las ventajas de usar AJAX, y nos comenta algunas otras cosas como el AJAX Control Toolkit y la librería jQuery.

- Enlaces
http://www.asp.net/ajax
http://www.asp.net/AJAX/AjaxControlToolkit/Samples</itunes:summary><link>http://channel9.msdn.com/posts/channel9spain/Introduccin-a-ASPNET-AJAX/</link><pubDate>Tue, 03 Nov 2009 00:17:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.mp4</guid><evnet:views>924</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/503738/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Elisa García Anzano, Academic Developer Advisor en Microsoft Ibérica, nos hace una introducción a ASP.NET AJAX. Un webcast muy práctico en el que Elisa nos muestra las ventajas de usar AJAX, y nos comenta algunas otras cosas como el AJAX Control Toolkit y la librería jQuery.&lt;br /&gt;</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.mp4" expression="full" duration="687" fileSize="33432374" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.mp3" expression="full" duration="687" fileSize="5497958" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.mp4" expression="full" duration="687" fileSize="33432374" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.wma" expression="full" duration="687" fileSize="5568379" type="audio/x-ms-wma" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_2MB_ch9.wmv" expression="full" duration="687" fileSize="133761607" type="video/x-ms-wmv" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.wmv" expression="full" duration="687" fileSize="51647131" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_2MB_ch9.wmv" expression="full" duration="687" fileSize="133761607" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_Zune_ch9.wmv" expression="full" duration="687" fileSize="36264382" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_512_ch9.png" expression="full" duration="687" type="image/jpeg" medium="image" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_2MB_ch9.wmv" expression="full" duration="687" fileSize="133761607" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_2MB_ch9.wmv" expression="full" duration="687" fileSize="133761607" type="video/x-ms-asf" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/8/3/7/3/0/5/IntroduccionASPNETAjaxElisa_ch9.mp4" length="33432374" type="video/mp4" /><dc:creator>Channel9Spain</dc:creator><itunes:author>Channel9Spain</itunes:author><slash:comments>1</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/channel9spain/Introduccin-a-ASPNET-AJAX/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/503738/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>ASP.NET AJAX</category><category>es-es</category><category>español</category><category>Spain</category><category>Spanish</category></item><item><title>ASP.NET Webcast Teil 1: ASP.NET Basisframework &amp; Übersicht, Webforms</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_85_ch9.png" border="0" /&gt;Teil 1 der Webcast Serie zu ASP.NET.&lt;br /&gt;
Die Serie im Überblick auf &lt;a href="http://webcast.codefest.at"&gt;webcast.codefest.at&lt;/a&gt;.&lt;br /&gt;&lt;img src="http://channel9.msdn.com/503264/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-1-ASPNET-Basisframework--bersicht-Webforms/</comments><itunes:summary>Teil 1 der Webcast Serie zu ASP.NET.
Die Serie im Überblick auf webcast.codefest.at.</itunes:summary><link>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-1-ASPNET-Basisframework--bersicht-Webforms/</link><pubDate>Fri, 30 Oct 2009 12:55:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.mp4</guid><evnet:views>1905</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/503264/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Teil 1 der Webcast Serie zu ASP.NET.
Die Serie im Überblick auf webcast.codefest.at.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.mp4" expression="full" duration="3414" fileSize="125142918" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.mp3" expression="full" duration="3414" fileSize="27316766" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.mp4" expression="full" duration="3414" fileSize="125142918" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.wma" expression="full" duration="3414" fileSize="27623747" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.wmv" expression="full" duration="3414" fileSize="164453323" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_2MB_ch9.wmv" expression="full" duration="3414" fileSize="230201929" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_Zune_ch9.wmv" expression="full" duration="3414" fileSize="118582527" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_512_ch9.png" expression="full" duration="3414" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/4/6/2/3/0/5/ASPNET01.ism/Manifest" expression="full" duration="3414" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/4/6/2/3/0/5/ASPNET01_ch9.mp4" length="125142918" type="video/mp4" /><dc:creator>codefest</dc:creator><itunes:author>codefest</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/codefest/ASPNET-Webcast-Teil-1-ASPNET-Basisframework--bersicht-Webforms/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/503264/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>codefest</category><category>webcast</category><category>webforms</category></item><item><title>MSDN TV - Publicera ASP.NET med Visual Studio 2008</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_85_ch9.png" border="0" /&gt;&lt;p&gt;I en serie kortare webcasts så vill jag nu försöka belysa hur enkelt det är att bygga applikationer med Microsofts verktyg och publicera resultatet på svenska “hosters”. I mina exempel använder jag mig av Binero.&lt;/p&gt;
&lt;p&gt;I den här filmen publicerar jag en vanlig ASP.NET WebForms applikationer med hjälp av Visual Studio 2008.&lt;/p&gt;&lt;img src="http://channel9.msdn.com/501600/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/johanlindfors/MSDN-TV-Publicera-ASPNET-med-Visual-Studio-2008/</comments><itunes:summary>I en serie kortare webcasts så vill jag nu försöka belysa hur enkelt det är att bygga applikationer med Microsofts verktyg och publicera resultatet på svenska “hosters”. I mina exempel använder jag mig av Binero.
I den här filmen publicerar jag en vanlig ASP.NET WebForms applikationer med hjälp av Visual Studio 2008.</itunes:summary><link>http://channel9.msdn.com/posts/johanlindfors/MSDN-TV-Publicera-ASPNET-med-Visual-Studio-2008/</link><pubDate>Fri, 23 Oct 2009 13:11:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.mp4</guid><evnet:views>1466</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/501600/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I en serie kortare webcasts så vill jag nu försöka belysa hur enkelt det är att bygga applikationer med Microsofts verktyg och publicera resultatet på svenska “hosters”. I mina exempel använder jag mig av Binero.
I den här filmen publicerar jag en vanlig ASP.NET WebForms applikationer med hjälp av Visual Studio 2008.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.mp4" expression="full" duration="289" fileSize="11178762" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.mp3" expression="full" duration="289" fileSize="2313355" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.mp4" expression="full" duration="289" fileSize="11178762" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.wma" expression="full" duration="289" fileSize="2348097" type="audio/x-ms-wma" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_2MB_ch9.wmv" expression="full" duration="289" fileSize="14281619" type="video/x-ms-wmv" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.wmv" expression="full" duration="289" fileSize="13561565" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_2MB_ch9.wmv" expression="full" duration="289" fileSize="14281619" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_Zune_ch9.wmv" expression="full" duration="289" fileSize="10448643" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_512_ch9.png" expression="full" duration="289" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/0/0/6/1/0/5/Binero1.ism/Manifest" expression="full" duration="289" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_2MB_ch9.wmv" expression="full" duration="289" fileSize="14281619" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_2MB_ch9.wmv" expression="full" duration="289" fileSize="14281619" type="video/x-ms-asf" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/0/0/6/1/0/5/Binero1_ch9.mp4" length="11178762" type="video/mp4" /><dc:creator>Johan Lindfors</dc:creator><itunes:author>Johan Lindfors</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/johanlindfors/MSDN-TV-Publicera-ASPNET-med-Visual-Studio-2008/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/501600/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>MSDN TV</category><category>Sweden</category><category>Visual Studio</category></item><item><title>Announcing Microsoft Ajax Library Preview 6</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_85_ch9.png" border="0" /&gt;I sat down with &lt;a href="http://www.stephenwalther.com"&gt;Stephen Walther&lt;/a&gt; from the Microsoft Ajax team to talk about their new release - Preview 6 - of the Microsoft Ajax Library.&lt;br /&gt;
&lt;br /&gt;
Stephen walks us through the three big enhancements in this release:&lt;br /&gt;
&lt;br /&gt;
- Addition of the imperative syntax&lt;br /&gt;
- The Script Loader&lt;br /&gt;
- jQuery support enhancements&lt;br /&gt;
&lt;br /&gt;
We go on to talk about how this will be the last release before we launch the Microsoft Ajax Library before the upcoming Microsoft PDC conference in November and also mention the new Microsoft Ajax CDN where we now have hosted the Microsoft Ajax Library and jQuery.&lt;br /&gt;
&lt;br /&gt;
To download the latest preview and get more information on the Microsoft Ajax Library head over to &lt;a href="http://www.asp.net/ajax"&gt;http://www.asp.net/ajax&lt;/a&gt; and also be sure to check out these related blog posts from the rest of the Microsoft Ajax team:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://weblogs.asp.net/scottgu/archive/2009/10/15/announcing-microsoft-ajax-library-preview-6-and-the-microsoft-ajax-minifier.aspx"&gt;Scott Guthrie has the big announcement&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.jamessenior.com/post/How-the-Script-Loader-in-the-Microsoft-Ajax-Library-will-make-your-life-wonderful.aspx"&gt;James Senior has details on the Script Loader&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx"&gt;Bertrand Le Roy has a blog post on imperative templates&lt;/a&gt;&lt;img src="http://channel9.msdn.com/497097/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/</comments><itunes:summary>I sat down with Stephen Walther from the Microsoft Ajax team to talk about their new release - Preview 6 - of the Microsoft Ajax Library.

Stephen walks us through the three big enhancements in this release:

- Addition of the imperative syntax
- The Script Loader
- jQuery support enhancements

We go on to talk about how this will be the last release before we launch the Microsoft Ajax Library before the upcoming Microsoft PDC conference in November and also mention the new Microsoft Ajax CDN where we now have hosted the Microsoft Ajax Library and jQuery.

To download the latest preview and get more information on the Microsoft Ajax Library head over to http://www.asp.net/ajax and also be sure to check out these related blog posts from the rest of the Microsoft Ajax team:

Scott Guthrie has the big announcement
James Senior has details on the Script Loader
Bertrand Le Roy has a blog post on imperative templates</itunes:summary><link>http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/</link><pubDate>Fri, 16 Oct 2009 10:47:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.mp4</guid><evnet:views>33684</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/497097/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I sat down with Stephen Walther from the Microsoft Ajax team to talk about their new release - Preview 6 - of the Microsoft Ajax Library.&lt;br /&gt;
&lt;br /&gt;
Stephen walks us through the three big enhancements in this release:&lt;br /&gt;
&lt;br /&gt;
- Addition of the imperative syntax&lt;br /&gt;
- The Script Loader&lt;br /&gt;
- jQuery support enhancements&lt;br /&gt;
&lt;br /&gt;
We go on to talk about how this will be the last release before we launch the Microsoft Ajax Library before the upcoming Microsoft PDC conference in November and also mention the new Microsoft Ajax CDN where we now have hosted the Microsoft Ajax Library and jQuery.&lt;br /&gt;
&lt;br /&gt;</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.mp4" expression="full" duration="1596" fileSize="129771821" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.mp3" expression="full" duration="1596" fileSize="12771712" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.mp4" expression="full" duration="1596" fileSize="129771821" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.wma" expression="full" duration="1596" fileSize="12916163" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.wmv" expression="full" duration="1596" fileSize="193451871" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_2MB_ch9.wmv" expression="full" duration="1596" fileSize="321128835" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_Zune_ch9.wmv" expression="full" duration="1596" fileSize="105386101" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_512_ch9.png" expression="full" duration="1596" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/7/9/0/7/9/4/announcingajaxpreview6.ism/Manifest" expression="full" duration="1596" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/7/9/0/7/9/4/announcingajaxpreview6_ch9.mp4" length="129771821" type="video/mp4" /><dc:creator>James Senior</dc:creator><itunes:author>James Senior</itunes:author><slash:comments>4</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/497097/Trackback.aspx</trackback:ping><category>Ajax</category><category>ASP.NET</category><category>ASP.NET AJAX</category><category>Javascript</category></item><item><title>Nya ving.se - en resa i arkitektur</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_85_ch9.png" border="0" /&gt;Anders Ljusberg, arkitekt på Tomas Cook, berättar om arkitekturen på nya ving.se.&lt;img src="http://channel9.msdn.com/496537/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/MSDNSweden/Nya-vingse-en-resa-i-arkitektur/</comments><itunes:summary>Anders Ljusberg, arkitekt på Tomas Cook, berättar om arkitekturen på nya ving.se.</itunes:summary><link>http://channel9.msdn.com/posts/MSDNSweden/Nya-vingse-en-resa-i-arkitektur/</link><pubDate>Wed, 07 Oct 2009 04:44:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp4</guid><evnet:views>2830</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/496537/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Anders Ljusberg, arkitekt på Tomas Cook, berättar om arkitekturen på nya ving.se.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp4" expression="full" duration="1321" fileSize="189711173" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp3" expression="full" duration="1321" fileSize="10573652" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp4" expression="full" duration="1321" fileSize="189711173" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.wma" expression="full" duration="1321" fileSize="10702221" type="audio/x-ms-wma" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_2MB_ch9.wmv" expression="full" duration="1321" fileSize="137427314" type="video/x-ms-wmv" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.wmv" expression="full" duration="1321" fileSize="236760027" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_2MB_ch9.wmv" expression="full" duration="1321" fileSize="137427314" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_Zune_ch9.wmv" expression="full" duration="1321" fileSize="104392007" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_512_ch9.png" expression="full" duration="1321" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/7/3/5/6/9/4/ving.ism/Manifest" expression="full" duration="1321" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp4" expression="full" duration="1321" fileSize="189711173" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_2MB_ch9.wmv" expression="full" duration="1321" fileSize="137427314" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_2MB_ch9.wmv" expression="full" duration="1321" fileSize="137427314" type="video/x-ms-asf" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/7/3/5/6/9/4/ving_ch9.mp4" length="189711173" type="video/mp4" /><dc:creator>Swedish MSDN Team</dc:creator><itunes:author>Swedish MSDN Team</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/MSDNSweden/Nya-vingse-en-resa-i-arkitektur/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/496537/Trackback.aspx</trackback:ping><category>Arkitektur</category><category>ASP.NET</category><category>MSDN Sweden</category><category>Sweden</category></item><item><title>Web Application Toolkit: Template-Driven Emails</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_85_ch9.png" border="0" /&gt;&lt;p&gt;This Web Application Toolkit is designed to demonstrate how to generate and send dynamic, template-based emails from a web application. There are many common scenarios where notification emails need to be sent to end users. Examples of these common scenarios may involve notifying a user of their newly created account, sending a new password in respond to a forgotten password request, or emailing an alert under specific business circumstances, such as the creation of a order. Typically the E-mails sent from a Web application scenario are formatted as HTML, include CSS stylesheets, and images and need to be generated dynamically with custom or user-specific data. &lt;/p&gt;
&lt;p&gt;This Web Application Toolkit provides a reusable component named TemplateDrivenEmail that can be used to easily generate and send dynamic, HTML-formatted emails based on templates that you can easily create and customize. The TemplateDrivenEmail component is a .NET Class Library that can easily be included in your solution and used with an ASP.NET Web Application, a background application such as a Windows Service, or any other type of .NET application. The email templates are based on a standard XML technology know as Extensible Stylesheet Language. This Web Application Toolkit also includes an example that shows how to use the TemplateDrivenEmail component.&lt;/p&gt;
Download this toolkit &lt;a href="http://code.msdn.microsoft.com/WebAppToolkitEmail"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
For screencasts about other Web Application Toolkits, click &lt;a href="http://channel9.msdn.com/tags/web+application+toolkit/"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To download other Web Application Toolkits, click &lt;a href="http://go.microsoft.com/fwlink/?LinkId=164753"&gt;here&lt;/a&gt;.&lt;img src="http://channel9.msdn.com/494054/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/LostInTangent/Web-Application-Toolkit-Template-Driven-Emails/</comments><itunes:summary>This Web Application Toolkit is designed to demonstrate how to generate and send dynamic, template-based emails from a web application. There are many common scenarios where notification emails need to be sent to end users. Examples of these common scenarios may involve notifying a user of their newly created account, sending a new password in respond to a forgotten password request, or emailing an alert under specific business circumstances, such as the creation of a order. Typically the E-mails sent from a Web application scenario are formatted as HTML, include CSS stylesheets, and images and need to be generated dynamically with custom or user-specific data. 
This Web Application Toolkit provides a reusable component named TemplateDrivenEmail that can be used to easily generate and send dynamic, HTML-formatted emails based on templates that you can easily create and customize. The TemplateDrivenEmail component is a .NET Class Library that can easily be included in your solution and used with an ASP.NET Web Application, a background application such as a Windows Service, or any other type of .NET application. The email templates are based on a standard XML technology know as Extensible Stylesheet Language. This Web Application Toolkit also includes an example that shows how to use the TemplateDrivenEmail component.
Download this toolkit here.

For screencasts about other Web Application Toolkits, click here.

To download other Web Application Toolkits, click here.</itunes:summary><link>http://channel9.msdn.com/posts/LostInTangent/Web-Application-Toolkit-Template-Driven-Emails/</link><pubDate>Thu, 24 Sep 2009 18:03:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.mp4</guid><evnet:views>5048</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/494054/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>This Web Application Toolkit is designed to demonstrate how to generate and send dynamic, template-based emails from a web application. There are many common scenarios where notification emails need to be sent to end users. Examples of these common scenarios may involve notifying a user of their newly created account, sending a new password in respond to a forgotten password request, or emailing an alert under specific business circumstances, such as the creation of a order. Typically the E-mails sent from a Web application scenario are formatted as HTML, include CSS stylesheets, and images and need to be generated dynamically with custom or user-specific data.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.mp4" expression="full" duration="746" fileSize="30245950" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.mp3" expression="full" duration="746" fileSize="5971318" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.mp4" expression="full" duration="746" fileSize="30245950" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.wma" expression="full" duration="746" fileSize="6052029" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.wmv" expression="full" duration="746" fileSize="33824029" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_2MB_ch9.wmv" expression="full" duration="746" fileSize="45296737" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_Zune_ch9.wmv" expression="full" duration="746" fileSize="23391957" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_512_ch9.png" expression="full" duration="746" type="image/jpeg" medium="image" /><media:content url="http://ss.channel9.msdn.com/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail.ism/Manifest" expression="full" duration="746" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_2MB_ch9.wmv" expression="full" duration="746" fileSize="45296737" type="video/x-ms-asf" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/4/5/0/4/9/4/WebAppToolkitTemplateDrivenEmail_ch9.mp4" length="30245950" type="video/mp4" /><dc:creator>Jonathan Carter</dc:creator><itunes:author>Jonathan Carter</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/LostInTangent/Web-Application-Toolkit-Template-Driven-Emails/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/494054/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Web Application Toolkit</category></item><item><title>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Refactoring Notification</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_85_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Refactoring Notification&lt;/h1&gt;
&lt;p&gt;The circular dependency problem between Pages and Users is due to each class implementing part of a larger notification feature. Once again this was not obvious when the two classes were coupled together via Singleton instances. Although the Single Responsibility Principle (SRP) would encourage us to have a separate Notification class, our primary job right now is to disentangle Pages and Users. Once the responsibility for notifications has been moved to one class or the other, it can be separated more easily into a separate Notification class. Let’s work on moving it to Pages.&lt;/p&gt;
&lt;p&gt;We’ll start by adding notification-related methods on IUsers to IPages (we won’t remove the methods from IUsers or Users yet):&lt;/p&gt;
&lt;pre&gt;public interface IPages {    ...    bool SetEmailNotification(UserInfo user, PageInfo page,      bool pageChanges, bool discussionMessages);    bool SetEmailNotification(UserInfo user, NamespaceInfo nspace,       bool pageChanges, bool discussionMessages);    void GetEmailNotification(UserInfo user, PageInfo page,       out bool pageChanges, out bool discussionMessages);    void GetEmailNotification(UserInfo user, NamespaceInfo nspace,       out bool pageChanges, out bool discussionMessages);    UserInfo[] GetUsersToNotifyForPageChange(PageInfo page);    UserInfo[] GetUsersToNotifyForDiscussionMessages(PageInfo page);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;We will implement these methods on Pages by temporarily delegating to Users:&lt;/p&gt;
&lt;pre&gt;public bool SetEmailNotification(UserInfo user, PageInfo page,                                 bool pageChanges, bool discussionMessages) {    return users.SetEmailNotification(user, page,                                       pageChanges, discussionMessages);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The other methods are implemented similarly. We can now look for usages of those methods on IUsers and change them to reference the same methods on IPages instead. The only usages for the IUsers methods should now be by Pages and the IUsers methods can be removed. You’ll have to temporarily cast the IUsers instances in the delegating methods to Users as the methods no longer exist on the IUsers interface:&lt;/p&gt;
&lt;pre&gt;public bool SetEmailNotification(UserInfo user, PageInfo page,                                 bool pageChanges, bool discussionMessages) {    return ((Users)users).SetEmailNotification(user, page,                                      pageChanges, discussionMessages);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Time to pack up the notification-related methods on Users and move them to their new home on Pages.&lt;/p&gt;
&lt;h2&gt;And That’s a Wrap&lt;/h2&gt;
&lt;p&gt;Simply by making the dependencies between classes explicit via dependency injection, we revealed a number of circular dependencies lurking in the ScrewTurn Wiki codebase. Circular dependencies between components effectively turn the individual components into one large super-structure, which is difficult to modify. Changes ripple through these super-structures and resulting in unexpected breakages after seemingly innocuous modifications. &lt;/p&gt;
&lt;p&gt;Applying the same techniques to Host’s other dependencies, we remove Host’s use of singletons altogether. (For the curious reader, the code is available for download from &lt;a href="http://code.msdn.microsoft.com/mag2009BFXASP"&gt;MSDN Code Gallery for Extreme ASP.NET Makeover&lt;/a&gt;.) Host’s constructor signature now looks like this:&lt;/p&gt;
&lt;pre&gt;public Host(ISettings settings, IAuthWriter authWriter, IUsers users,         IPages pages, ISnippets snippets, INavigationPaths navigationPaths)&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Its dependencies are obvious in a way that they were not before. Host has a fair number of dependencies, but it is acting as a facade between ScrewTurn Wiki and the plug-ins. So it is not overly worrying.&lt;/p&gt;
&lt;p&gt;We can start asking ourselves meta questions about our software:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Do these dependencies make sense? &lt;/li&gt;
    &lt;li&gt;Should some of these dependencies be combined/split? &lt;/li&gt;
    &lt;li&gt;How do the dependencies relate to one another and can those relationships be improved? &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can reason about the overall structure of our software and improve it because that structure is more apparent. In the end, our software becomes more flexible, more testable, and more resilient in the face of change.&lt;/p&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;I would like to thank Dario Solera, creator of ScrewTurn Wiki, for being brave and open in allowing me to use ScrewTurn Wiki as the brownfield application throughout this series. He has already taken the constructive criticism provided in earlier articles and used it to improve the latest builds of ScrewTurn Wiki. Kudos to Dario for permitting all of us to learn together out in the open.&lt;/p&gt;
&lt;p&gt;Thank you to my two occasional co-authors, Kyle Baley and Donald Belcham, for their assistance on parts 6 and 7. Your insights were invaluable in pushing the series forward. Dario has agreed to allow ScrewTurn Wiki to be used as the sample brownfield application for Kyle and Donald’s upcoming book, &lt;i&gt;Brownfield Application Development in .NET&lt;/i&gt;, published by Manning. If you want more information about improving brownfield applications, their book is an excellent resource.&lt;/p&gt;
&lt;p&gt;A big thanks to Howard Dierking for giving me the latitude and encouragement to take the series where I thought would be most useful and practical. Thanks also to Gary Clarke and the rest of the &lt;i&gt;MSDN Magazine&lt;/i&gt; staff for their helpful suggestions, patience, and quick turn-around while editing the series.&lt;/p&gt;
&lt;p&gt;Finally, I would like to offer special thanks to my spouse, Risa Kawchuk, and my two sons, Daegan and Gareth, for their understanding in not having as much spouse/daddy time in the last few months as I’ve toiled away evenings and weekends on these articles and screencasts.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/"&gt;Dependency&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/"&gt;Host Users Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/"&gt;Circular Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/"&gt;Refactoring Notification&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee470637.aspx"&gt;http://msdn.microsoft.com/magazine/ee470637.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/491010/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/</comments><itunes:summary>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Refactoring Notification
The circular dependency problem between Pages and Users is due to each class implementing part of a larger notification feature. Once again this was not obvious when the two classes were coupled together via Singleton instances. Although the Single Responsibility Principle (SRP) would encourage us to have a separate Notification class, our primary job right now is to disentangle Pages and Users. Once the responsibility for notifications has been moved to one class or the other, it can be separated more easily into a separate Notification class. Let’s work on moving it to Pages.
We’ll start by adding notification-related methods on IUsers to IPages (we won’t remove the methods from IUsers or Users yet):
public interface IPages {    ...    bool SetEmailNotification(UserInfo user, PageInfo page,      bool pageChanges, bool discussionMessages);    bool SetEmailNotification(UserInfo user, NamespaceInfo nspace,       bool pageChanges, bool discussionMessages);    void GetEmailNotification(UserInfo user, PageInfo page,       out bool pageChanges, out bool discussionMessages);    void GetEmailNotification(UserInfo user, NamespaceInfo nspace,       out bool pageChanges, out bool discussionMessages);    UserInfo[] GetUsersToNotifyForPageChange(PageInfo page);    UserInfo[] GetUsersToNotifyForDiscussionMessages(PageInfo page);}

We will implement these methods on Pages by temporarily delegating to Users:
public bool SetEmailNotification(UserInfo user, PageInfo page,                                 bool pageChanges, bool discussionMessages) {    return users.SetEmailNotification(user, page,                                       pageChanges, discussionMessages);}

The other methods are implemented similarly. We can now look for usages of those methods on IUsers and change them to reference the same methods on IPages instead. The only usages for the IUsers methods should now be by Pages and the IUsers methods can be removed. You’ll have to temporarily cast the IUsers instances in the delegating methods to Users as the methods no longer exist on the IUsers interface:
public bool SetEmailNotification(UserInfo user, PageInfo page,                                 bool pageChanges, bool discussionMessages) {    return ((Users)users).SetEmailNotification(user, page,                                      pageChanges, discussionMessages);}

Time to pack up the notification-related methods on Users and move them to their new home on Pages.
And That’s a Wrap
Simply by making the dependencies between classes explicit via dependency injection, we revealed a number of circular dependencies lurking in the ScrewTurn Wiki codebase. Circular dependencies between components effectively turn the individual components into one large super-structure, which is difficult to modify. Changes ripple through these super-structures and resulting in unexpected breakages after seemingly innocuous modifications. 
Applying the same techniques to Host’s other dependencies, we remove Host’s use of singletons altogether. (For the curious reader, the code is available for download from MSDN Code Gallery for Extreme ASP.NET Makeover.) Host’s constructor signature now looks like this:
public Host(ISettings settings, IAuthWriter authWriter, IUsers users,         IPages pages, ISnippets snippets, INavigationPaths navigationPaths)

Its dependencies are obvious in a way that they were not before. Host has a fair number of dependencies, but it is acting as a facade between ScrewTurn Wiki and the plug-ins. So it is not overly worrying.
We can start asking ourselves meta questions about our software:

    Do these dependencies make sense? 
    Should some of these dependencies be combined/split? 
    How do the dependencies relate to one another and can those relationships be improved? 

We can reason about the overall structure of our software and improve it because that structure is more apparent. In the end, our software becomes more flexible, more testable, and more resilient in the face of change.
Acknowledgements
I would like to thank Dario Solera, creator of ScrewTurn Wiki, for being brave and open in allowing me to use ScrewTurn Wiki as the brownfield application throughout this series. He has already taken the constructive criticism provided in earlier articles and used it to improve the latest builds of ScrewTurn Wiki. Kudos to Dario for permitting all of us to learn together out in the open.
Thank you to my two occasional co-authors, Kyle Baley and Donald Belcham, for their assistance on parts 6 and 7. Your insights were invaluable in pushing the series forward. Dario has agreed to allow ScrewTurn Wiki to be used as the sample brownfield application for Kyle and Donald’s upcoming book, Brownfield Application Development in .NET, published by Manning. If you want more information about improving brownfield applications, their book is an excellent resource.
A big thanks to Howard Dierking for giving me the latitude and encouragement to take the series where I thought would be most useful and practical. Thanks also to Gary Clarke and the rest of the MSDN Magazine staff for their helpful suggestions, patience, and quick turn-around while editing the series.
Finally, I would like to offer special thanks to my spouse, Risa Kawchuk, and my two sons, Daegan and Gareth, for their understanding in not having as much spouse/daddy time in the last few months as I’ve toiled away evenings and weekends on these articles and screencasts.
Other videos from this article

    Overview 
    Dependency 
    Host Users Dependency Cycle 
    Circular Dependency Cycle 
    Refactoring Notification 

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx</itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/</link><pubDate>Fri, 11 Sep 2009 18:18:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.mp4</guid><evnet:views>3833</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/491010/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>The circular dependency problem between Pages and Users is due to each class implementing part of a larger notification feature. Once again this was not obvious when the two classes were coupled together via Singleton instances. Although the Single Responsibility Principle (SRP) would encourage us to have a separate Notification class, our primary job right now is to disentangle Pages and Users. Once the responsibility for notifications has been moved to one class or the other, it can be separated more easily into a separate Notification class. Let’s work on moving it to Pages.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.mp4" expression="full" duration="655" fileSize="22819755" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.mp3" expression="full" duration="655" fileSize="5245821" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.mp4" expression="full" duration="655" fileSize="22819755" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.wma" expression="full" duration="655" fileSize="5307031" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.wmv" expression="full" duration="655" fileSize="43406749" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_2MB_ch9.wmv" expression="full" duration="655" fileSize="45492622" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_Zune_ch9.wmv" expression="full" duration="655" fileSize="23182677" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_512_ch9.png" expression="full" duration="655" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/0/1/0/1/9/4/RefactoringNotifications_ch9.mp4" length="22819755" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>1</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/491010/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category></item><item><title>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Circular Dependency Cycle</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_85_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Circular Dependency Cycle&lt;/h1&gt;
&lt;p&gt;The only reason for Users to reference Host is to raise events on behalf of the Users class. We can quickly and easily remove this dependency by allowing Users to raise its own events, as shown in &lt;b&gt;Figure 4&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 4 Users Raises Its Own Events&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class Users : IUsers {  public event     EventHandler&amp;lt;UserAccountActivityEventArgs&amp;gt; UserAccountChanged;  private void OnUserAccountChanged(UserInfo user,    UserAccountActivity activity) {      if(UserAccountChanged != null) {        UserAccountChanged(this,           new UserAccountActivityEventArgs(user, activity));      }  }  public event     EventHandler&amp;lt;UserGroupActivityEventArgs&amp;gt; UserGroupChanged;  private void OnUserGroupChanged(UserGroup group,    UserGroupActivity activity) {    if(UserGroupChanged != null) {      UserGroupChanged(this,        new UserGroupActivityEventArgs(group, activity));    }  }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Host can now subscribe to the Users.UserAccountChanged and Users.UserGroupChanged events and re-broadcast those events to interested listeners without breaking the facade by exposing the Users class directly, as &lt;b&gt;Figure 5&lt;/b&gt; shows.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 5 Host Can Subscribe to the Users.UserAccountChanged and Users.UserGroupChanged Events&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class Host : IHostV30 {    public Host(ISettings settings, IUsers users) {        customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);        this.settings = settings;        this.users = users;        users.UserAccountChanged += OnUserAccountActivity;        users.UserGroupChanged += OnUserGroupActivity;    }    public event EventHandler&amp;lt;UserAccountActivityEventArgs&amp;gt; UserAccountActivity;    private void OnUserAccountActivity(object sender,      UserAccountActivityEventArgs args) {        if(UserAccountActivity != null) {            UserAccountActivity(this, args);        }    }    public event EventHandler&amp;lt;UserGroupActivityEventArgs&amp;gt; UserGroupActivity;    private void OnUserGroupActivity(object sender,       UserGroupActivityEventArgs args) {        if(UserGroupActivity != null) {            UserGroupActivity(this, args);        }    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Users no longer needs a reference to Host and it can be safely removed from Users’ constructor. We have broken the circular dependency between Host and Users. Running our tests, we see that everything is green again.&lt;/p&gt;
&lt;p&gt;Before we move on, notice how the circular dependency problem wasn’t immediately noticeable when the classes were linked together using Singletons. Singletons, due to their global nature, make it easy for dependencies to spill between classes. Using the dependency injection principle, it is much easier to see a class’s dependencies because most of them are in the constructor and the remainder are method parameters.&lt;/p&gt;
&lt;h2&gt;Don’t You Forget about IoC&lt;/h2&gt;
&lt;p&gt;With apologies to Billy Idol, we cannot forget about the container. It is responsible for creating and wiring together our dependencies. Looking at ScrewTurnWikiInitializationTask, we see the following:&lt;/p&gt;
&lt;pre&gt;Users.Instance = new Users();&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Classes that take a dependency on IUsers are going to get an instance of Users supplied through their constructor, but classes that access Users.Instance are going to get a different Users instance. We can solve this minor problem by allowing the IoC container to supply ScrewTurnWikiInitializationTask with an IUsers instance through its constructor. We now have:&lt;/p&gt;
&lt;pre&gt;public ScrewTurnWikiInitializationTask(IHostV30 host,          ISettingsStorageProviderV30 settingsStorageProvider, IUsers users) {    this.host = host;    this.settingsStorageProvider = settingsStorageProvider;    this.users = users;}public void Execute() {    ...    Users.Instance = users;    ....}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;While we’re talking about the container, let’s look at HostAnProviderRegistration:&lt;/p&gt;
&lt;pre&gt;public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            Component.For&amp;lt;IHostV30&amp;gt;().ImplementedBy&amp;lt;Host&amp;gt;(),            Component.For&amp;lt;ISettings&amp;gt;().ImplementedBy&amp;lt;Settings&amp;gt;(),            Component.For&amp;lt;IUsers&amp;gt;().ImplementedBy&amp;lt;Users&amp;gt;());        ...    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;You’ll notice that we’re starting to get a lot of repetitive code. This is a great place to establish a convention rather than manually configuring each dependency. Let’s create a ScrewTurn.Wiki.Hosting namespace and register each dependency in that namespace against its first interface:&lt;/p&gt;
&lt;pre&gt;public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            AllTypes.FromAssembly(Assembly.GetExecutingAssembly())                .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Hosting"))                .WithService.FirstInterface()        );        ...    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;As we refactor dependencies, we need only place them in this namespace (achieved by moving them to the Hosting folder in ScrewTurn.Wiki.Core) and they will automatically be registered correctly in the IoC container.&lt;/p&gt;
&lt;h2&gt;The Journey Continues&lt;/h2&gt;
&lt;p&gt;Users depends on the Settings.Instance and Pages.Instance Singletons. These are quickly extracted into constructor dependencies as before. Pages gets the same treatment as Users—moving to ScrewTurn.Wiki.Hosting namespace (for automatic IoC registration through our convention), interface extraction, and pushing dependent Singletons to constructor parameters. (Additional tests were added to ensure that IPages can be resolved from the IoC container and that Pages.Instance is properly initialized.)&lt;/p&gt;
&lt;p&gt;Pages has the same problem as Users in that it uses Host to raise events on its behalf. The same procedure is applied whereby Pages is refactored to raise its own events, which Host then registers for and re-raises to interested listeners. Once again, we’ve broken an unnecessary coupling between two classes, Pages and Host this time. For those interested in the details, you can check out the code download associated with the article.&lt;/p&gt;
&lt;p&gt;Pages makes use of many other Singletons and the refactoring continues in much the same vein until we get to Users. Once we move Users into a constructor parameter, our tests break. Pages depends on Users and Users depends on Pages. We’ve uncovered another circular dependency issue. Let’s take a closer look.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/"&gt;Dependency&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/"&gt;Host Users Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/"&gt;Circular Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/"&gt;Refactoring Notification&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee470637.aspx"&gt;http://msdn.microsoft.com/magazine/ee470637.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/491009/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/</comments><itunes:summary>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Circular Dependency Cycle
The only reason for Users to reference Host is to raise events on behalf of the Users class. We can quickly and easily remove this dependency by allowing Users to raise its own events, as shown in Figure 4.
Figure 4 Users Raises Its Own Events
public class Users : IUsers {  public event     EventHandler&amp;lt;UserAccountActivityEventArgs&amp;gt; UserAccountChanged;  private void OnUserAccountChanged(UserInfo user,    UserAccountActivity activity) {      if(UserAccountChanged != null) {        UserAccountChanged(this,           new UserAccountActivityEventArgs(user, activity));      }  }  public event     EventHandler&amp;lt;UserGroupActivityEventArgs&amp;gt; UserGroupChanged;  private void OnUserGroupChanged(UserGroup group,    UserGroupActivity activity) {    if(UserGroupChanged != null) {      UserGroupChanged(this,        new UserGroupActivityEventArgs(group, activity));    }  }}

Host can now subscribe to the Users.UserAccountChanged and Users.UserGroupChanged events and re-broadcast those events to interested listeners without breaking the facade by exposing the Users class directly, as Figure 5 shows.
Figure 5 Host Can Subscribe to the Users.UserAccountChanged and Users.UserGroupChanged Events
public class Host : IHostV30 {    public Host(ISettings settings, IUsers users) {        customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);        this.settings = settings;        this.users = users;        users.UserAccountChanged += OnUserAccountActivity;        users.UserGroupChanged += OnUserGroupActivity;    }    public event EventHandler&amp;lt;UserAccountActivityEventArgs&amp;gt; UserAccountActivity;    private void OnUserAccountActivity(object sender,      UserAccountActivityEventArgs args) {        if(UserAccountActivity != null) {            UserAccountActivity(this, args);        }    }    public event EventHandler&amp;lt;UserGroupActivityEventArgs&amp;gt; UserGroupActivity;    private void OnUserGroupActivity(object sender,       UserGroupActivityEventArgs args) {        if(UserGroupActivity != null) {            UserGroupActivity(this, args);        }    }}

Users no longer needs a reference to Host and it can be safely removed from Users’ constructor. We have broken the circular dependency between Host and Users. Running our tests, we see that everything is green again.
Before we move on, notice how the circular dependency problem wasn’t immediately noticeable when the classes were linked together using Singletons. Singletons, due to their global nature, make it easy for dependencies to spill between classes. Using the dependency injection principle, it is much easier to see a class’s dependencies because most of them are in the constructor and the remainder are method parameters.
Don’t You Forget about IoC
With apologies to Billy Idol, we cannot forget about the container. It is responsible for creating and wiring together our dependencies. Looking at ScrewTurnWikiInitializationTask, we see the following:
Users.Instance = new Users();

Classes that take a dependency on IUsers are going to get an instance of Users supplied through their constructor, but classes that access Users.Instance are going to get a different Users instance. We can solve this minor problem by allowing the IoC container to supply ScrewTurnWikiInitializationTask with an IUsers instance through its constructor. We now have:
public ScrewTurnWikiInitializationTask(IHostV30 host,          ISettingsStorageProviderV30 settingsStorageProvider, IUsers users) {    this.host = host;    this.settingsStorageProvider = settingsStorageProvider;    this.users = users;}public void Execute() {    ...    Users.Instance = users;    ....}

While we’re talking about the container, let’s look at HostAnProviderRegistration:
public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            Component.For&amp;lt;IHostV30&amp;gt;().ImplementedBy&amp;lt;Host&amp;gt;(),            Component.For&amp;lt;ISettings&amp;gt;().ImplementedBy&amp;lt;Settings&amp;gt;(),            Component.For&amp;lt;IUsers&amp;gt;().ImplementedBy&amp;lt;Users&amp;gt;());        ...    }}

You’ll notice that we’re starting to get a lot of repetitive code. This is a great place to establish a convention rather than manually configuring each dependency. Let’s create a ScrewTurn.Wiki.Hosting namespace and register each dependency in that namespace against its first interface:
public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            AllTypes.FromAssembly(Assembly.GetExecutingAssembly())                .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Hosting"))                .WithService.FirstInterface()        );        ...    }}

As we refactor dependencies, we need only place them in this namespace (achieved by moving them to the Hosting folder in ScrewTurn.Wiki.Core) and they will automatically be registered correctly in the IoC container.
The Journey Continues
Users depends on the Settings.Instance and Pages.Instance Singletons. These are quickly extracted into constructor dependencies as before. Pages gets the same treatment as Users—moving to ScrewTurn.Wiki.Hosting namespace (for automatic IoC registration through our convention), interface extraction, and pushing dependent Singletons to constructor parameters. (Additional tests were added to ensure that IPages can be resolved from the IoC container and that Pages.Instance is properly initialized.)
Pages has the same problem as Users in that it uses Host to raise events on its behalf. The same procedure is applied whereby Pages is refactored to raise its own events, which Host then registers for and re-raises to interested listeners. Once again, we’ve broken an unnecessary coupling between two classes, Pages and Host this time. For those interested in the details, you can check out the code download associated with the article.
Pages makes use of many other Singletons and the refactoring continues in much the same vein until we get to Users. Once we move Users into a constructor parameter, our tests break. Pages depends on Users and Users depends on Pages. We’ve uncovered another circular dependency issue. Let’s take a closer look.
Other videos from this article

    Overview 
    Dependency 
    Host Users Dependency Cycle 
    Circular Dependency Cycle 
    Refactoring Notification 

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx</itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/</link><pubDate>Fri, 11 Sep 2009 18:17:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.mp4</guid><evnet:views>2954</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/491009/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>The only reason for Users to reference Host is to raise events on behalf of the Users class. We can quickly and easily remove this dependency by allowing Users to raise its own events</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.mp4" expression="full" duration="105" fileSize="3013668" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.mp3" expression="full" duration="105" fileSize="842623" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.mp4" expression="full" duration="105" fileSize="3013668" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.wma" expression="full" duration="105" fileSize="858113" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.wmv" expression="full" duration="105" fileSize="4631055" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_2MB_ch9.wmv" expression="full" duration="105" fileSize="3666772" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_Zune_ch9.wmv" expression="full" duration="105" fileSize="2918983" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_512_ch9.png" expression="full" duration="105" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/9/0/0/1/9/4/UsersPagesCircularDependencyProblem_ch9.mp4" length="3013668" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/491009/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category></item><item><title>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Host Users Dependency Cycle</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_85_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Host Users Dependency Cycle&lt;/h1&gt;
&lt;br /&gt;
&lt;h2&gt;Going Around in Circles&lt;/h2&gt;
&lt;p&gt;We successfully refactored away Host’s dependency on Settings.Instance by allowing the IoC container to pass Host an instance of ISettings via its constructor. It seems like a simple matter to continue refactoring away Host’s dependencies on the other Singletons, but trouble is brewing just around the corner. The next Singleton we extract is Users.Instance. Following exactly the same procedure as Settings.Instance, we discover a horrible secret - a CircularDependencyException.&lt;/p&gt;
&lt;p&gt;Let’s take a look at the constructors for Host and Users:&lt;/p&gt;
&lt;pre&gt;public Host(ISettings settings, IUsers users) {    customSpecialTags =         new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);    this.settings = settings;    this.users = users;}public Users(IHostV30 host) {    this.host = host;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;So Host depends on Users and Users depends on Host. Before the refactoring, this dependency cycle wasn’t obvious. The two components are in fact much more tightly coupled to one another than expected. Let’s take a deeper look at Users to find out where this coupling is coming from.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/"&gt;Dependency&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/"&gt;Host Users Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/"&gt;Circular Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/"&gt;Refactoring Notification&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee470637.aspx"&gt;http://msdn.microsoft.com/magazine/ee470637.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/491007/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/</comments><itunes:summary>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Host Users Dependency Cycle

Going Around in Circles
We successfully refactored away Host’s dependency on Settings.Instance by allowing the IoC container to pass Host an instance of ISettings via its constructor. It seems like a simple matter to continue refactoring away Host’s dependencies on the other Singletons, but trouble is brewing just around the corner. The next Singleton we extract is Users.Instance. Following exactly the same procedure as Settings.Instance, we discover a horrible secret - a CircularDependencyException.
Let’s take a look at the constructors for Host and Users:
public Host(ISettings settings, IUsers users) {    customSpecialTags =         new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);    this.settings = settings;    this.users = users;}public Users(IHostV30 host) {    this.host = host;}

So Host depends on Users and Users depends on Host. Before the refactoring, this dependency cycle wasn’t obvious. The two components are in fact much more tightly coupled to one another than expected. Let’s take a deeper look at Users to find out where this coupling is coming from.
Other videos from this article

    Overview 
    Dependency 
    Host Users Dependency Cycle 
    Circular Dependency Cycle 
    Refactoring Notification 

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx</itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/</link><pubDate>Fri, 11 Sep 2009 18:17:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.mp4</guid><evnet:views>2886</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/491007/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>&lt;p&gt;We successfully refactored away Host’s dependency on Settings.Instance by allowing the IoC container to pass Host an instance of ISettings via its constructor. It seems like a simple matter to continue refactoring away Host’s dependencies on the other Singletons, but trouble is brewing just around the corner. The next Singleton we extract is Users.Instance. Following exactly the same procedure as Settings.Instance, we discover a horrible secret - a CircularDependencyException.&lt;/p&gt;</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.mp4" expression="full" duration="81" fileSize="2299663" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.mp3" expression="full" duration="81" fileSize="656844" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.mp4" expression="full" duration="81" fileSize="2299663" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.wma" expression="full" duration="81" fileSize="668861" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.wmv" expression="full" duration="81" fileSize="3446719" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_2MB_ch9.wmv" expression="full" duration="81" fileSize="2364136" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_Zune_ch9.wmv" expression="full" duration="81" fileSize="2214647" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_512_ch9.png" expression="full" duration="81" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/7/0/0/1/9/4/ExaminingHostUsersDependencyCycle_ch9.mp4" length="2299663" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/491007/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category></item><item><title>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Dependency</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_85_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Dependency&lt;/h1&gt;
&lt;p&gt;As we saw, the Host class delegates to a whole host of Singletons (bad pun intended), including Settings, Users, Pages, Snippets, NavigationPaths, and AuthWriter. Each of these Singletons refers to other Singletons, creating a morass of dependencies. Before we start refactoring Host, we need some tests in place to ensure that we are not breaking anything. Configuration of the application and infrastructure is done by the ApplicationBootstrapper, which we introduced in Part 8. Our tests are going to execute ApplicationBootstrapper.Configure, as shown in &lt;b&gt;Figure 2&lt;/b&gt;, and then verify that IHostV30 can be resolved from the IoC container as well as that various Singletons are still configured properly. Note that the IoC is initialized to null after every test to ensure that the tests don’t interfere with one another.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 2 Tests Execute ApplicationBootstrapper.Configure&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;[TestFixture]public class AfterTheApplicationBootstraperIsExecuted {    [Test]    public void IHostCanBeResolvedFromTheContainer() {        IoC.Resolve&amp;lt;IHostV30&amp;gt;();    }    [Test]    public void CacheInstanceIsInitialized() {        Assert.That(Cache.Instance, Is.Not.Null);    }    public void SettingsInstanceIsInitialized() {        Assert.That(Settings.Instance, Is.Not.Null);    }    [Test]    public void AuthReaderInstanceIsInitialized() {        Assert.That(AuthReader.Instance, Is.Not.Null);    }    [Test]    public void AuthWriterInstanceIsInitialized() {        Assert.That(AuthWriter.Instance, Is.Not.Null);    }    [SetUp]    public void SetUp() {        new ApplicationBootstrapper().Configure();    }    [TearDown]    public void TearDown() {        IoC.Initialize(null);    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;With these tests in place, let’s start refactoring Host to expose its dependency problems.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/"&gt;Dependency&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/"&gt;Host Users Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/"&gt;Circular Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/"&gt;Refactoring Notification&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee470637.aspx"&gt;http://msdn.microsoft.com/magazine/ee470637.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/491006/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/</comments><itunes:summary>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready –Dependency
As we saw, the Host class delegates to a whole host of Singletons (bad pun intended), including Settings, Users, Pages, Snippets, NavigationPaths, and AuthWriter. Each of these Singletons refers to other Singletons, creating a morass of dependencies. Before we start refactoring Host, we need some tests in place to ensure that we are not breaking anything. Configuration of the application and infrastructure is done by the ApplicationBootstrapper, which we introduced in Part 8. Our tests are going to execute ApplicationBootstrapper.Configure, as shown in Figure 2, and then verify that IHostV30 can be resolved from the IoC container as well as that various Singletons are still configured properly. Note that the IoC is initialized to null after every test to ensure that the tests don’t interfere with one another.
Figure 2 Tests Execute ApplicationBootstrapper.Configure
[TestFixture]public class AfterTheApplicationBootstraperIsExecuted {    [Test]    public void IHostCanBeResolvedFromTheContainer() {        IoC.Resolve&amp;lt;IHostV30&amp;gt;();    }    [Test]    public void CacheInstanceIsInitialized() {        Assert.That(Cache.Instance, Is.Not.Null);    }    public void SettingsInstanceIsInitialized() {        Assert.That(Settings.Instance, Is.Not.Null);    }    [Test]    public void AuthReaderInstanceIsInitialized() {        Assert.That(AuthReader.Instance, Is.Not.Null);    }    [Test]    public void AuthWriterInstanceIsInitialized() {        Assert.That(AuthWriter.Instance, Is.Not.Null);    }    [SetUp]    public void SetUp() {        new ApplicationBootstrapper().Configure();    }    [TearDown]    public void TearDown() {        IoC.Initialize(null);    }}

With these tests in place, let’s start refactoring Host to expose its dependency problems.
Other videos from this article

    Overview 
    Dependency 
    Host Users Dependency Cycle 
    Circular Dependency Cycle 
    Refactoring Notification 

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx</itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/</link><pubDate>Fri, 11 Sep 2009 18:17:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.mp4</guid><evnet:views>2984</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/491006/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>As we saw, the Host class delegates to a whole host of Singletons (bad pun intended), including Settings, Users, Pages, Snippets, NavigationPaths, and AuthWriter. Each of these Singletons refers to other Singletons, creating a morass of dependencies. Before we start refactoring Host, we need some tests in place to ensure that we are not breaking anything. Configuration of the application and infrastructure is done by the ApplicationBootstrapper, which we introduced in Part 8. Our tests are going to execute ApplicationBootstrapper.Configure, as shown in Figure 2, and then verify that IHostV30 can be resolved from the IoC container as well as that various Singletons are still configured properly. Note that the IoC is initialized to null after every test to ensure that the tests don’t interfere with one another.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.mp4" expression="full" duration="432" fileSize="11956805" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.mp3" expression="full" duration="432" fileSize="3464033" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.mp4" expression="full" duration="432" fileSize="11956805" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.wma" expression="full" duration="432" fileSize="3513643" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.wmv" expression="full" duration="432" fileSize="16203627" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_2MB_ch9.wmv" expression="full" duration="432" fileSize="10534940" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_Zune_ch9.wmv" expression="full" duration="432" fileSize="11547555" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_512_ch9.png" expression="full" duration="432" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/6/0/0/1/9/4/ExposingTheDependencyProblem_ch9.mp4" length="11956805" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/491006/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category></item><item><title>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready - Overview</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_85_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready -Overview&lt;/h1&gt;
&lt;p&gt;We’re now on the ninth installment of Extreme ASP.NET Makeover. In part 8, we discovered that the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can lead to unexpected NullReferenceExceptions after apparently innocuous changes to the code. We refactored AuthorizationChecker to eliminate the dependency problems, but we did not address the elephant in the room—ScrewTurn.Wiki.Host. This article confronts the problems of ScrewTurn.Wiki.Host head-on in an effort to tame its wild ways.&lt;/p&gt;
&lt;h2&gt;Another Look at Host&lt;/h2&gt;
&lt;p&gt;Host’s primary purpose is to act as a facade between ScrewTurn Wiki’s plug-ins (aka “Providers”) and ScrewTurn Wiki itself. Host allows plug-ins to do everything from retrieving settings values to sending emails to handling backups to finding users, Wiki pages, namespaces, categories, and more, as shown in &lt;b&gt;Figure 1&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 1 IHostV30&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The plug-ins, which implement IProviderV30, are initialized with a Host instance and a configuration string through their Init method:&lt;/p&gt;
&lt;pre&gt;public interface IProviderV30 {    void Init(IHostV30 host, string config);    void Shutdown();    ComponentInformation Information { get; }    string ConfigHelpHtml { get; }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Looking at Host’s constructor, no dependency problems are immediately evident:&lt;/p&gt;
&lt;pre&gt;public class Host : IHostV30 {    public Host() {        customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);    }    ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The plug-in system seems fairly innocuous, but the devil is in the details. Let’s dig a little deeper and see what we find.&lt;/p&gt;
&lt;h2&gt;The First Step is Realizing You Have a Problem&lt;/h2&gt;
&lt;p&gt;Given Host’s role as a facade object for the plug-in system and its overly simplistic constructor, I suspect that there is a dependency problem lurking beneath the surface. So I have enrolled Host in Dependency-aholics Anonymous. The first step in this twelve-step program is to make Host’s dependencies obvious, just as we did in part 8 when working with AuthorizationChecker.&lt;/p&gt;
&lt;p&gt;I’m not too concerned at the moment about static helper classes, such as ScrewTurn.Wiki.Tools or ScrewTurn.Wiki.Formatter. Static helper classes are often a rich source of inspiration for domain concepts. For example, if you have helper methods for performing arithmetic operations on currency, introduce a Money class to encapsulate the data and behavior. If you have helper methods comparing whole dates, introduce a Date class. Yes, .NET has a DateTime class, but it includes both the date and the time. Don’t be afraid to create a Date or Time class that is tailored to the needs of your application. If you deal with financial data, working with a strongly-typed FiscalPeriod class is going to be a lot easier than passing around DateTime objects and remembering to call Helpers.ConvertToFiscal(someDate) to ensure that the DateTime is properly aligned to a fiscal period.&lt;/p&gt;
&lt;p&gt;But static helpers aren’t our concern at the moment because these are most often simple stateless methods that have little to no coupling to the rest of the application. We are looking for hidden dependencies that wind their tentacles insidiously throughout the application. The dependencies that have dependencies that have dependencies ad infinitum, resulting in unnecessary coupling and rigidity in the codebase. To find these, we need look no further than the Singletons to which Host delegates much of its responsibilities.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Dependency/"&gt;Dependency&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Host-Users-Dependency-Cycle/"&gt;Host Users Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Circular-Dependency-Cycle/"&gt;Circular Dependency Cycle&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Refactoring-Notification/"&gt;Refactoring Notification&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee470637.aspx"&gt;http://msdn.microsoft.com/magazine/ee470637.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/491005/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/</comments><itunes:summary>Extreme ASP.NET Makeover: Mr. Escher, Your Software is Ready -Overview
We’re now on the ninth installment of Extreme ASP.NET Makeover. In part 8, we discovered that the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can lead to unexpected NullReferenceExceptions after apparently innocuous changes to the code. We refactored AuthorizationChecker to eliminate the dependency problems, but we did not address the elephant in the room—ScrewTurn.Wiki.Host. This article confronts the problems of ScrewTurn.Wiki.Host head-on in an effort to tame its wild ways.
Another Look at Host
Host’s primary purpose is to act as a facade between ScrewTurn Wiki’s plug-ins (aka “Providers”) and ScrewTurn Wiki itself. Host allows plug-ins to do everything from retrieving settings values to sending emails to handling backups to finding users, Wiki pages, namespaces, categories, and more, as shown in Figure 1.
 
Figure 1 IHostV30
The plug-ins, which implement IProviderV30, are initialized with a Host instance and a configuration string through their Init method:
public interface IProviderV30 {    void Init(IHostV30 host, string config);    void Shutdown();    ComponentInformation Information { get; }    string ConfigHelpHtml { get; }}

Looking at Host’s constructor, no dependency problems are immediately evident:
public class Host : IHostV30 {    public Host() {        customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);    }    ...}

The plug-in system seems fairly innocuous, but the devil is in the details. Let’s dig a little deeper and see what we find.
The First Step is Realizing You Have a Problem
Given Host’s role as a facade object for the plug-in system and its overly simplistic constructor, I suspect that there is a dependency problem lurking beneath the surface. So I have enrolled Host in Dependency-aholics Anonymous. The first step in this twelve-step program is to make Host’s dependencies obvious, just as we did in part 8 when working with AuthorizationChecker.
I’m not too concerned at the moment about static helper classes, such as ScrewTurn.Wiki.Tools or ScrewTurn.Wiki.Formatter. Static helper classes are often a rich source of inspiration for domain concepts. For example, if you have helper methods for performing arithmetic operations on currency, introduce a Money class to encapsulate the data and behavior. If you have helper methods comparing whole dates, introduce a Date class. Yes, .NET has a DateTime class, but it includes both the date and the time. Don’t be afraid to create a Date or Time class that is tailored to the needs of your application. If you deal with financial data, working with a strongly-typed FiscalPeriod class is going to be a lot easier than passing around DateTime objects and remembering to call Helpers.ConvertToFiscal(someDate) to ensure that the DateTime is properly aligned to a fiscal period.
But static helpers aren’t our concern at the moment because these are most often simple stateless methods that have little to no coupling to the rest of the application. We are looking for hidden dependencies that wind their tentacles insidiously throughout the application. The dependencies that have dependencies that have dependencies ad infinitum, resulting in unnecessary coupling and rigidity in the codebase. To find these, we need look no further than the Singletons to which Host delegates much of its responsibilities.
Other videos from this article

    Overview 
    Dependency 
    Host Users Dependency Cycle 
    Circular Dependency Cycle 
    Refactoring Notification 

Read the full article at http://msdn.microsoft.com/magazine/ee470637.aspx</itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/</link><pubDate>Fri, 11 Sep 2009 18:17:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.mp4</guid><evnet:views>3290</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/491005/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>We’re now on the ninth installment of Extreme ASP.NET Makeover. In part 8, we discovered that the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can lead to unexpected NullReferenceExceptions after apparently innocuous changes to the code. We refactored AuthorizationChecker to eliminate the dependency problems, but we did not address the elephant in the room—ScrewTurn.Wiki.Host. This article confronts the problems of ScrewTurn.Wiki.Host head-on in an effort to tame its wild ways.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.mp4" expression="full" duration="149" fileSize="4228634" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.mp3" expression="full" duration="149" fileSize="1196183" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.mp4" expression="full" duration="149" fileSize="4228634" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.wma" expression="full" duration="149" fileSize="1218593" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.wmv" expression="full" duration="149" fileSize="6103671" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_2MB_ch9.wmv" expression="full" duration="149" fileSize="4201320" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_Zune_ch9.wmv" expression="full" duration="149" fileSize="4215599" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_512_ch9.png" expression="full" duration="149" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/5/0/0/1/9/4/TheTroubleWithTribblesIMeanSingletons_ch9.mp4" length="4228634" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Mr-Escher-Your-Software-is-Ready-Overview/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/491005/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category></item><item><title>ASP.NET Databinding and jQueryUI</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_85_ch9.png" border="0" /&gt;In this installment of DevNuggets, Developer Evangelist G. Andrew Duthie (aka &lt;a href="http://blogs.msdn.com/gduthie/" title="DEvHammer blog."&gt;DEvHammer&lt;/a&gt;) demonstrates how you can easily add fun and function to your ASP.NET-based website using &lt;a href="http://jqueryui.com/"&gt;jQueryUI&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
This DevNugget is a follow-up to &lt;a href="http://channel9.msdn.com/posts/gduthie/Using-jQuery-UI-in-ASPNET/"&gt;Andrew's introduction to using jQueryUI in ASP.NET&lt;/a&gt; and in it you'll see how easy it is to dynamically generate the markup required to build a jQueryUI Accordion widget using an ASP.NET Repeater control bound to an ADO.NET Data Service. Databinding with a Repeater makes it quick and easy to generate clean markup that's tailor-made for integration with jQueryUI.&lt;br /&gt;
&lt;br /&gt;
You can keep track of what's happening with the DEvHammer on his &lt;a href="http://blogs.msdn.com/gduthie/"&gt;blog&lt;/a&gt;, or on &lt;a href="http://twitter.com/devhammer/"&gt;Twitter&lt;/a&gt;, and find out about upcoming developer and IT Pro events in your area on his site, &lt;a href="http://www.communitymegaphone.com/"&gt;Community Megaphone&lt;/a&gt;.&lt;img src="http://channel9.msdn.com/490021/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/gduthie/ASPNET-Databinding-and-jQueryUI/</comments><itunes:summary>In this installment of DevNuggets, Developer Evangelist G. Andrew Duthie (aka DEvHammer) demonstrates how you can easily add fun and function to your ASP.NET-based website using jQueryUI.

This DevNugget is a follow-up to Andrew's introduction to using jQueryUI in ASP.NET and in it you'll see how easy it is to dynamically generate the markup required to build a jQueryUI Accordion widget using an ASP.NET Repeater control bound to an ADO.NET Data Service. Databinding with a Repeater makes it quick and easy to generate clean markup that's tailor-made for integration with jQueryUI.

You can keep track of what's happening with the DEvHammer on his blog, or on Twitter, and find out about upcoming developer and IT Pro events in your area on his site, Community Megaphone.</itunes:summary><link>http://channel9.msdn.com/posts/gduthie/ASPNET-Databinding-and-jQueryUI/</link><pubDate>Sat, 05 Sep 2009 23:12:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.mp4</guid><evnet:views>4867</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/490021/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>In this installment of DevNuggets, Developer Evangelist G. Andrew Duthie (aka &lt;a href="http://blogs.msdn.com/gduthie/" title="DEvHammer blog."&gt;DEvHammer&lt;/a&gt;) demonstrates how you can easily add fun and function to your ASP.NET-based website using &lt;a href="http://jqueryui.com/"&gt;jQueryUI&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
This DevNugget is a follow-up to &lt;a href="http://channel9.msdn.com/posts/gduthie/Using-jQuery-UI-in-ASPNET/"&gt;Andrew's introduction to using jQueryUI in ASP.NET&lt;/a&gt; and in it you'll see how easy it is to dynamically generate the markup required to build a jQueryUI Accordion widget using an ASP.NET Repeater control bound to an ADO.NET Data Service. Databinding with a Repeater makes it quick and easy to generate clean markup that's tailor-made for integration with jQueryUI.&lt;br /&gt;</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.mp4" expression="full" duration="417" fileSize="13171972" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.mp3" expression="full" duration="417" fileSize="3340236" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.mp4" expression="full" duration="417" fileSize="13171972" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.wma" expression="full" duration="417" fileSize="3381473" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_2MB_ch9.wmv" expression="full" duration="417" fileSize="31719949" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_2MB_ch9.wmv" expression="full" duration="417" fileSize="31719949" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_Zune_ch9.wmv" expression="full" duration="417" fileSize="12811351" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_512_ch9.png" expression="full" duration="417" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/1/2/0/0/9/4/aspnetdbjqueryui_ch9.mp4" length="13171972" type="video/mp4" /><dc:creator>G. Andrew Duthie</dc:creator><itunes:author>G. Andrew Duthie</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/gduthie/ASPNET-Databinding-and-jQueryUI/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/490021/Trackback.aspx</trackback:ping><category>ADO.NET Data Services</category><category>ASP.NET</category><category>Databinding</category><category>DevNuggets</category><category>dpeeast</category><category>jQueryUI</category><category>MidAtlantic</category><category>Visual Studio</category></item><item><title>Navigating through the hypes, Software architectures and patterns to help avoiding your projects to crash. (Dutch)</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_85_ch9.png" border="0" /&gt;When it comes to .Net software development, more and more frameworks enter the market. Both from Microsoft and in open source. Just think of all the very useful frameworks, such as ASP.NET MVC, Castle, WF, Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, WCF, nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF. Once a project chooses to apply one or more frameworks, trouble begins. What if you require additional features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway your project? What if the author of your favorite open source framework suddenly stops developing? What if the framework contains bugs or omissions? And what if a new version of the framework is released that is implemented totally different? These and many more everyday problems will cause your project to come to a halt, or at least make you perform serious refactoring. During this highly interactive talk Sander Hoogendoorn, principal technology officer at Capgemini, chief architect of Capgemini’s agile Accelerated Delivery Platform, and member of Microsoft’s Visual Studio Advisory Board, will demonstrate pragmatic software architectures and patterns that will help your projects to stay away from framework problems, and how to keep your code independent of framework choices. In his well known slightly ironic style Sander will present different models of layered architectures, and explain and use bridge patterns, managers, dependency injection, descriptors, and layer super-types. Of course, the speaker will illustrate these insightful patterns with lots of demo’s and (bad) code examples using blocks from Microsoft’s Enterprise Library, nHibernate, Log4Net, and the Entity Framework. Delegates will benefit from this talk by learning how to improve the structure and quality of their software architecture and code, and how to avoid the pitfalls of applying frameworks to .Net software development. &lt;br /&gt;
&lt;br /&gt;
Deze video is opgenomen tijdens de DevDays in Den Haag in juni 2009. DevDays is het grootste evenement op het vlak van softwareontwikkeling en -architectuur in Nederland. Duizenden development professionals bezoeken dit jaarlijkse evenement om in twee dagen weer volledig op de hoogte te zijn van alle ontwikkelingen op hun vakgebied.&lt;img src="http://channel9.msdn.com/472572/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/matthijs/Navigating-through-the-hypes-Software-architectures-and-patterns-to-help-avoiding-your-projects-to-c/</comments><itunes:summary>When it comes to .Net software development, more and more frameworks enter the market. Both from Microsoft and in open source. Just think of all the very useful frameworks, such as ASP.NET MVC, Castle, WF, Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, WCF, nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF. Once a project chooses to apply one or more frameworks, trouble begins. What if you require additional features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway your project? What if the author of your favorite open source framework suddenly stops developing? What if the framework contains bugs or omissions? And what if a new version of the framework is released that is implemented totally different? These and many more everyday problems will cause your project to come to a halt, or at least make you perform serious refactoring. During this highly interactive talk Sander Hoogendoorn, principal technology officer at Capgemini, chief architect of Capgemini’s agile Accelerated Delivery Platform, and member of Microsoft’s Visual Studio Advisory Board, will demonstrate pragmatic software architectures and patterns that will help your projects to stay away from framework problems, and how to keep your code independent of framework choices. In his well known slightly ironic style Sander will present different models of layered architectures, and explain and use bridge patterns, managers, dependency injection, descriptors, and layer super-types. Of course, the speaker will illustrate these insightful patterns with lots of demo’s and (bad) code examples using blocks from Microsoft’s Enterprise Library, nHibernate, Log4Net, and the Entity Framework. Delegates will benefit from this talk by learning how to improve the structure and quality of their software architecture and code, and how to avoid the pitfalls of applying frameworks to .Net software development. 

Deze video is opgenomen tijdens de DevDays in Den Haag in juni 2009. DevDays is het grootste evenement op het vlak van softwareontwikkeling en -architectuur in Nederland. Duizenden development professionals bezoeken dit jaarlijkse evenement om in twee dagen weer volledig op de hoogte te zijn van alle ontwikkelingen op hun vakgebied.</itunes:summary><link>http://channel9.msdn.com/posts/matthijs/Navigating-through-the-hypes-Software-architectures-and-patterns-to-help-avoiding-your-projects-to-c/</link><pubDate>Fri, 04 Sep 2009 13:01:00 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/posts/matthijs/Navigating-through-the-hypes-Software-architectures-and-patterns-to-help-avoiding-your-projects-to-c/</guid><evnet:views>3290</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/472572/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>When it comes to .Net software development, more and more frameworks enter the market. Both from Microsoft and in open source. Just think of all the very useful frameworks, such as ASP.NET MVC, Castle, WF, Entity Framework, Unity, Linq2SQL, ADO.NET Data Services, WCF, nHibernate, Spring.NET, CSLA, NUnit, Enterprise Library or ADF. Once a project chooses to apply one or more frameworks, trouble begins. What if you require additional features that aren’t implemented in the framework? What if you decide that another framework would have been better and want to switch halfway your project? What if…</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_2MB_ch9.wmv" expression="full" duration="3864" fileSize="591582928" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_512_ch9.png" expression="full" duration="3864" type="image/jpeg" medium="image" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/2/7/5/2/7/4/ARC03SH_2MB_ch9.wmv" expression="full" duration="3864" fileSize="591582928" type="video/x-ms-asf" medium="video" /></media:group><dc:creator>Matthijs Hoekstra</dc:creator><itunes:author>Matthijs Hoekstra</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/matthijs/Navigating-through-the-hypes-Software-architectures-and-patterns-to-help-avoiding-your-projects-to-c/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/472572/Trackback.aspx</trackback:ping><category>ADO.NET</category><category>ASP.NET</category><category>DevDays 2009 NL</category><category>LINQ</category><category>Sander Hoogendoorn</category><category>WCF</category><category>WF</category></item><item><title>Extreme ASP.NET Makeover: Disentangling Our Tangled Web-Overview - Refactoring</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_85_ch9.png" border="0" /&gt;&lt;h2&gt;A Topsy-Turvy World&lt;/h2&gt;
&lt;p&gt;The constructor signature for AuthorizationChecker now looks like this:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker(    ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools,     IAclEvaluator aclEvaluator) { ... }&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;We can clearly see that AuthorizationChecker depends on implementations of ISettingsStorageProviderV30, IAuthTools, and IAclEvalator, but we are not concerned with the actual implementations. This is the dependency inversion principle at work.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;"High-level modules should not depend on low-level modules. Both should depend on abstractions."&lt;/i&gt; – Robert C. Martin (&lt;a href="http://objectmentor.com/resources/articles/dip.pdf"&gt;http://objectmentor.com/resources/articles/dip.pdf&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;In this case, AuthorizationChecker and AuthTools don’t depend on each other, but depend on the abstraction provided by IAuthTools. The same is true for AuthorizationChecker’s other two dependencies, ISettingsStorageProviderV30 and IAclEvaluator.&lt;/p&gt;
&lt;p&gt;We have decoupled AuthorizationChecker from its dependencies. The question remains that AuthorizationChecker still needs these dependencies supplied at run-time to actually be able to execute. The simplest way to supply these dependences as default implementations via AuthorizationChecker's parameterless constructor:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker() :     this(Settings.Instance.Provider,         new AuthTools(), new AclEvaluator()) {}&lt;/pre&gt;
&lt;br /&gt;
&lt;h2&gt;Of Containers and Castles&lt;/h2&gt;
&lt;p&gt;A more flexible way to supply dependencies is to use an Inversion of Control container, such as &lt;a href="http://castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt;. Castle Windsor is a set of assemblies that we reference from our code. We simply register all of our dependencies in the container and then ask the container for an implementation. The container walks the dependency chain, creates objects in the correct order, supplying dependencies as it creates objects further up the dependency chain until it can finally return us a fully constructed object. Consider the following code:&lt;/p&gt;
&lt;pre&gt;var authorizationServices = IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;();&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The IoC is a static gateway class that provides an abstraction so that your code is not dependent on a particular IoC container for retrieving dependencies. It is similar in interface and approach to Microsoft’s &lt;a href="http://commonservicelocator.codeplex.com/"&gt;Common Service Locator&lt;/a&gt; available on CodePlex. You can read more about the IoC static gateway in &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc337885.aspx"&gt;“Loosen Up: Tame Your Software Dependencies for More Flexible Apps”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In order for Castle Windsor to satisfy this request for an implementation of IAuthorizationServices, we’ll need to register the dependencies:&lt;/p&gt;
&lt;pre&gt;var ssp = ProviderLoader.LoadSettingsStorageProvider(    WebConfigurationManager.AppSettings["SettingsStorageProvider"]);container.Register(    AllTypes.FromAssembly(Assembly.GetExecutingAssembly())        .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Services"))        .WithService.FirstInterface(),    Component.For&amp;lt;IAclEvaluator&amp;gt;().ImplementedBy&amp;lt;AclEvaluator&amp;gt;(),    Component.For&amp;lt;ISettingsStorageProviderV30&amp;gt;().Instance(ssp));&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;This code is located in the ScrewTurn.Wiki.Core assembly. Rather than manually configuring each dependency individually, we use a convention-based approach whereby any types in the ScrewTurn.Wiki.Services namespace are registered via their first interface. This means that AuthorizationServices is registered as IAuthorizationServices, AuthTools is registered as IAuthTools, and similarly for other types in this namespace. This has the advantage that by placing services in the ScrewTurn.Wiki.Services namespace, they will automatically be registered in the container without requiring explicit configuration. Other classes can then take dependencies on these services simply by adding the appropriate interface to their own constructor.&lt;/p&gt;
&lt;p&gt;AclEvaluator is located in the ScrewTurn.Wiki.AclEngine assembly. Since it is the only dependency in this assembly, we register it explicitly. There isn’t a great deal of value from having a separate assembly for ScrewTurn.Wiki.AclEngine and I would consider merging the AclEngine project into Core. AclEvaluator could then be placed in the ScrewTurn.Wiki.Services namespace and auto-registered like the other dependencies. For the moment, AclEvaluator serves as an example of how to explicitly configure dependencies in Castle Windsor.&lt;/p&gt;
&lt;p&gt;ScrewTurn Wiki has code that dynamically loads a particular ISettingsStorageProviderV30 implementation specified by a fully qualified class name in a configuration file. Although we could use Castle Windsor’s configuration facilities to configure and load the appropriate assembly and implementation, that is not the current focus. We can leverage the existing loading mechanism by supplying Castle Windsor with a fully constructed instance via the Component.For&amp;lt;T&amp;gt;().Instance(obj) syntax.&lt;/p&gt;
&lt;p&gt;Windsor provides many more configuration options, including overrides, parameters, XML configuration, and more. You can find a lot more information on configuration options in Castle Windsor in my article, &lt;a href="http://code-magazine.com/Article.aspx?quickid=0906051"&gt;Bricks and Mortar: Building a Castle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now that AuthorizationServices and all of its dependencies have been registered with the container, we can successfully resolve it from the container:&lt;/p&gt;
&lt;pre&gt;var authorizationServices = IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;();&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;To service this request, Windsor will look for an implementer of IAuthorizationServices, which is AuthorizationServices. Windsor will then examine AuthorizationServices constructor, specifically the constructor parameters:&lt;/p&gt;
&lt;pre&gt;public AuthorizationServices(IAuthorizationChecker authorizationChecker) {    this.authorizationChecker = authorizationChecker;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Windsor will look to see if it has an implementation registered for IAuthorizationChecker, which it does in the form of AuthorizationChecker. Looking at AuthorizationChecker’s constructors:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker() : this(Settings.Instance.Provider,     new AuthTools(), new AclEvaluator()) {}public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools, IAclEvaluator aclEvaluator) {    ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Windsor has two constructors to choose from. It starts from the constructor with the most overloads. It will see if it has implementations for all of the constructor parameters. (If it can’t find implementations for all constructor parameters, Windsor will attempt the next most overloaded constructor.) In this case, it will see that it needs to find an implementation for ISettingsStorageProviderV30, IAuthTools, and IAclEvaluator. Windsor has an instance of ISettingsStorageProviderV30 that we supplied to it earlier. It can also create instances of AuthTools and AclEvaluator because they have no further dependencies. Windsor passes the newly created AuthTools and AclEvaluator, as well as the pre-built ISettingsStorageProviderV30 to AuthorizationChecker’s constructor. Windsor then passes the newly created AuthorizationChecker to AuthorizationServices’ constructor. Finally, Windsor is able to pass back AuthorizationServices to satisfy the call to IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;.&lt;/p&gt;
&lt;p&gt;Note that Windsor is responsible for managing the lifetime of objects registered in the container. Windsor’s default lifetime strategy is singleton. That means that multiple classes depending on IAuthorizationServices will all receive the same instance of AuthorizationServices. This instancing policy is easily changed on a per-service basis and includes options such as per-thread, per-Web-request, transient, and pooled. You can even create your own instancing policies if none of the built-in ones are appropriate.&lt;/p&gt;
&lt;p&gt;With the container responsible for wiring dependencies between objects, we can remove the parameterless constructors as they are no longer required:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools, IAclEvaluator aclEvaluator) {     ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;If AuthorizationChecker required another dependency, we would simply declare that fact by adding another constructor parameter with a type of the required service interface. We would then create a concrete class in the ScrewTurn.Wiki.Services namespace that implements that service interface.&lt;/p&gt;
&lt;h2&gt;Managing the Container&lt;/h2&gt;
&lt;p&gt;I have seen many projects place all container configuration into a single XML or C# file. This is especially unwieldy if explicitly configuring dependencies individually, which is why I prefer the convention-over-configuration approach discussed above. By placing dependencies in certain assemblies and namespaces, they are automatically registered. (Note that the convention-over-configuration approach is not available with XML files, although XML files are useful for specifying deployment-time overrides if necessary. For more information about this technique, see &lt;a href="http://code-magazine.com/Article.aspx?quickid=0906051"&gt;Bricks and Mortar: Building a Castle&lt;/a&gt;.) Placing all of our conventions in a single C# file can quickly become cumbersome as we have unrelated conventions bundled together.&lt;/p&gt;
&lt;p&gt;Let’s take a look at an approach that allows us to separate our conventions into smaller, simpler classes. It all starts with the ApplicationBootstrapper, which is called during application startup:&lt;/p&gt;
&lt;pre&gt;public void Configure() {    container = new WindsorContainer();    IoC.Initialize(new WindsorDependencyResolver(container));    RegisterFacilityStartupTasks();    ExecuteFacilityStartupTasks();    RegisterContainerStartupTasks();    ExecuteContainerStartupTasks();    RegisterStartupTasks();    ExecuteStartupTasks();}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;We start by creating a new WindsorContainer and using it to initialize the IoC static gateway. We then alternately register and execute FacilityStartup, ContainerStartup, and Startup tasks, as shown in &lt;b&gt;Figure 2&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 2 Execute FacilityStartup, ContainerStartup, and Startup Tasks&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;private void RegisterFacilityStartupTasks() {    RegisterAllTypesBasedOn&amp;lt;IFacilityStartupTask&amp;gt;();}private void RegisterContainerStartupTasks() {    RegisterAllTypesBasedOn&amp;lt;IContainerStartupTask&amp;gt;();}private void RegisterStartupTasks() {   RegisterAllTypesBasedOn&amp;lt;IStartupTask&amp;gt;();}private void RegisterAllTypesBasedOn&amp;lt;T&amp;gt;() {    assembliesToScan.ForEach(assembly =&amp;gt;         container.Register(            AllTypes.FromAssembly(assembly)                    .BasedOn&amp;lt;T&amp;gt;()                    .WithService.FirstInterface())    );}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The list of assemblies to scan for startup tasks is provided via AssemblyBootstrapper’s constructor and defaults to Assembly.GetExecutingAssembly if left unspecified. We look through each assembly for types implementing IFacilityStartupTask, IContainerStartupTask, and IStartupTask and register them against the appropriate interface. (Facilities are Windsor’s primary extension mechanism. You can use facilities to implement everything from automatic transaction management to logging to array parameter resolution and more.) Next, we need to execute each of the startup tasks:&lt;/p&gt;
&lt;pre&gt;private void ExecuteFacilityStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IFacilityStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute(container));}private void ExecuteContainerStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IContainerStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute(container));}private void ExecuteStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute());}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Note that IFacilityStartupTask|IContainerStartupTask.Execute both take an IWindsorContainer, as their purpose is to configure the container. IStartupTask.Execute is to perform other types of initialization once the container is ready to be used and therefore doesn’t accept an IWindsorContainer.&lt;/p&gt;
&lt;p&gt;The individual startup tasks are small and self-contained. For example, take a look at the ServiceRegistration class, which is responsible for registering application-related services:&lt;/p&gt;
&lt;pre&gt;public class ServicesRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            AllTypes.FromAssembly(Assembly.GetExecutingAssembly())                .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Services"))                .WithService.FirstInterface(),            Component.For&amp;lt;IAclEvaluator&amp;gt;().ImplementedBy&amp;lt;AclEvaluator&amp;gt;()        );    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;You can see the convention responsible for registering all services in the ScrewTurn.Wiki.Services namespace. There is also the extra configuration for the AclEvaluator. If we choose to combine the AclEngine project into Core, we could eliminate the extra configuration step for AclEvaluator.&lt;/p&gt;
&lt;p&gt;We have a completely separate and independent IContainerStartupTask for Host and Provider registration:&lt;/p&gt;
&lt;pre&gt;public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            Component.For&amp;lt;IHostV30&amp;gt;().ImplementedBy&amp;lt;Host&amp;gt;());        var ssp = ProviderLoader.LoadSettingsStorageProvider(            WebConfigurationManager.AppSettings["SettingsStorageProvider"]);        container.Register(            Component.For&amp;lt;ISettingsStorageProviderV30&amp;gt;().Instance(ssp));    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;As we break apart the “God object” that is the Host, we can modify its container registration in one place without affecting the registration of the services. If we need to perform additional unrelated container configuration, we create another class that implements the IFacilityStartupTask or IContainerStartupTask without affecting other configuration that is already taking place.&lt;/p&gt;
&lt;p&gt;To wrap up, let’s refactor StartupTools.Startup() into a IStartupTask where it belongs:&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Although it is not initially obvious, the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can result in unexpected NullReferenceExceptions after apparently innocuous changes to the code.&lt;/p&gt;
&lt;p&gt;In this article, we have made dependencies obvious by changing them into constructor parameters and using an IoC container to wire together the dependencies. Using convention-over-configuration approaches eases the introduction of new functionality, without requiring explicit configuration. We have introduced a reusable ApplicationBootstrapper, whereby new startup tasks can be added as the application grows without modifying existing code. The resulting codebase should be more flexible and maintainable over time.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Refactoring/"&gt;Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee424155.aspx"&gt;http://msdn.microsoft.com/magazine/ee424155.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/487028/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Refactoring/</comments><itunes:summary>A Topsy-Turvy World
The constructor signature for AuthorizationChecker now looks like this:
public AuthorizationChecker(    ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools,     IAclEvaluator aclEvaluator) { ... }

We can clearly see that AuthorizationChecker depends on implementations of ISettingsStorageProviderV30, IAuthTools, and IAclEvalator, but we are not concerned with the actual implementations. This is the dependency inversion principle at work.
"High-level modules should not depend on low-level modules. Both should depend on abstractions." – Robert C. Martin (http://objectmentor.com/resources/articles/dip.pdf)
In this case, AuthorizationChecker and AuthTools don’t depend on each other, but depend on the abstraction provided by IAuthTools. The same is true for AuthorizationChecker’s other two dependencies, ISettingsStorageProviderV30 and IAclEvaluator.
We have decoupled AuthorizationChecker from its dependencies. The question remains that AuthorizationChecker still needs these dependencies supplied at run-time to actually be able to execute. The simplest way to supply these dependences as default implementations via AuthorizationChecker's parameterless constructor:
public AuthorizationChecker() :     this(Settings.Instance.Provider,         new AuthTools(), new AclEvaluator()) {}

Of Containers and Castles
A more flexible way to supply dependencies is to use an Inversion of Control container, such as Castle Windsor. Castle Windsor is a set of assemblies that we reference from our code. We simply register all of our dependencies in the container and then ask the container for an implementation. The container walks the dependency chain, creates objects in the correct order, supplying dependencies as it creates objects further up the dependency chain until it can finally return us a fully constructed object. Consider the following code:
var authorizationServices = IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;();

The IoC is a static gateway class that provides an abstraction so that your code is not dependent on a particular IoC container for retrieving dependencies. It is similar in interface and approach to Microsoft’s Common Service Locator available on CodePlex. You can read more about the IoC static gateway in “Loosen Up: Tame Your Software Dependencies for More Flexible Apps”.
In order for Castle Windsor to satisfy this request for an implementation of IAuthorizationServices, we’ll need to register the dependencies:
var ssp = ProviderLoader.LoadSettingsStorageProvider(    WebConfigurationManager.AppSettings["SettingsStorageProvider"]);container.Register(    AllTypes.FromAssembly(Assembly.GetExecutingAssembly())        .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Services"))        .WithService.FirstInterface(),    Component.For&amp;lt;IAclEvaluator&amp;gt;().ImplementedBy&amp;lt;AclEvaluator&amp;gt;(),    Component.For&amp;lt;ISettingsStorageProviderV30&amp;gt;().Instance(ssp));

This code is located in the ScrewTurn.Wiki.Core assembly. Rather than manually configuring each dependency individually, we use a convention-based approach whereby any types in the ScrewTurn.Wiki.Services namespace are registered via their first interface. This means that AuthorizationServices is registered as IAuthorizationServices, AuthTools is registered as IAuthTools, and similarly for other types in this namespace. This has the advantage that by placing services in the ScrewTurn.Wiki.Services namespace, they will automatically be registered in the container without requiring explicit configuration. Other classes can then take dependencies on these services simply by adding the appropriate interface to their own constructor.
AclEvaluator is located in the ScrewTurn.Wiki.AclEngine assembly. Since it is the only dependency in this assembly, we register it explicitly. There isn’t a great deal of value from having a separate assembly for ScrewTurn.Wiki.AclEngine and I would consider merging the AclEngine project into Core. AclEvaluator could then be placed in the ScrewTurn.Wiki.Services namespace and auto-registered like the other dependencies. For the moment, AclEvaluator serves as an example of how to explicitly configure dependencies in Castle Windsor.
ScrewTurn Wiki has code that dynamically loads a particular ISettingsStorageProviderV30 implementation specified by a fully qualified class name in a configuration file. Although we could use Castle Windsor’s configuration facilities to configure and load the appropriate assembly and implementation, that is not the current focus. We can leverage the existing loading mechanism by supplying Castle Windsor with a fully constructed instance via the Component.For&amp;lt;T&amp;gt;().Instance(obj) syntax.
Windsor provides many more configuration options, including overrides, parameters, XML configuration, and more. You can find a lot more information on configuration options in Castle Windsor in my article, Bricks and Mortar: Building a Castle.
Now that AuthorizationServices and all of its dependencies have been registered with the container, we can successfully resolve it from the container:
var authorizationServices = IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;();

To service this request, Windsor will look for an implementer of IAuthorizationServices, which is AuthorizationServices. Windsor will then examine AuthorizationServices constructor, specifically the constructor parameters:
public AuthorizationServices(IAuthorizationChecker authorizationChecker) {    this.authorizationChecker = authorizationChecker;}

Windsor will look to see if it has an implementation registered for IAuthorizationChecker, which it does in the form of AuthorizationChecker. Looking at AuthorizationChecker’s constructors:
public AuthorizationChecker() : this(Settings.Instance.Provider,     new AuthTools(), new AclEvaluator()) {}public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools, IAclEvaluator aclEvaluator) {    ...}

Windsor has two constructors to choose from. It starts from the constructor with the most overloads. It will see if it has implementations for all of the constructor parameters. (If it can’t find implementations for all constructor parameters, Windsor will attempt the next most overloaded constructor.) In this case, it will see that it needs to find an implementation for ISettingsStorageProviderV30, IAuthTools, and IAclEvaluator. Windsor has an instance of ISettingsStorageProviderV30 that we supplied to it earlier. It can also create instances of AuthTools and AclEvaluator because they have no further dependencies. Windsor passes the newly created AuthTools and AclEvaluator, as well as the pre-built ISettingsStorageProviderV30 to AuthorizationChecker’s constructor. Windsor then passes the newly created AuthorizationChecker to AuthorizationServices’ constructor. Finally, Windsor is able to pass back AuthorizationServices to satisfy the call to IoC.Resolve&amp;lt;IAuthorizationServices&amp;gt;.
Note that Windsor is responsible for managing the lifetime of objects registered in the container. Windsor’s default lifetime strategy is singleton. That means that multiple classes depending on IAuthorizationServices will all receive the same instance of AuthorizationServices. This instancing policy is easily changed on a per-service basis and includes options such as per-thread, per-Web-request, transient, and pooled. You can even create your own instancing policies if none of the built-in ones are appropriate.
With the container responsible for wiring dependencies between objects, we can remove the parameterless constructors as they are no longer required:
public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools, IAclEvaluator aclEvaluator) {     ...}

If AuthorizationChecker required another dependency, we would simply declare that fact by adding another constructor parameter with a type of the required service interface. We would then create a concrete class in the ScrewTurn.Wiki.Services namespace that implements that service interface.
Managing the Container
I have seen many projects place all container configuration into a single XML or C# file. This is especially unwieldy if explicitly configuring dependencies individually, which is why I prefer the convention-over-configuration approach discussed above. By placing dependencies in certain assemblies and namespaces, they are automatically registered. (Note that the convention-over-configuration approach is not available with XML files, although XML files are useful for specifying deployment-time overrides if necessary. For more information about this technique, see Bricks and Mortar: Building a Castle.) Placing all of our conventions in a single C# file can quickly become cumbersome as we have unrelated conventions bundled together.
Let’s take a look at an approach that allows us to separate our conventions into smaller, simpler classes. It all starts with the ApplicationBootstrapper, which is called during application startup:
public void Configure() {    container = new WindsorContainer();    IoC.Initialize(new WindsorDependencyResolver(container));    RegisterFacilityStartupTasks();    ExecuteFacilityStartupTasks();    RegisterContainerStartupTasks();    ExecuteContainerStartupTasks();    RegisterStartupTasks();    ExecuteStartupTasks();}

We start by creating a new WindsorContainer and using it to initialize the IoC static gateway. We then alternately register and execute FacilityStartup, ContainerStartup, and Startup tasks, as shown in Figure 2.
Figure 2 Execute FacilityStartup, ContainerStartup, and Startup Tasks
private void RegisterFacilityStartupTasks() {    RegisterAllTypesBasedOn&amp;lt;IFacilityStartupTask&amp;gt;();}private void RegisterContainerStartupTasks() {    RegisterAllTypesBasedOn&amp;lt;IContainerStartupTask&amp;gt;();}private void RegisterStartupTasks() {   RegisterAllTypesBasedOn&amp;lt;IStartupTask&amp;gt;();}private void RegisterAllTypesBasedOn&amp;lt;T&amp;gt;() {    assembliesToScan.ForEach(assembly =&amp;gt;         container.Register(            AllTypes.FromAssembly(assembly)                    .BasedOn&amp;lt;T&amp;gt;()                    .WithService.FirstInterface())    );}

The list of assemblies to scan for startup tasks is provided via AssemblyBootstrapper’s constructor and defaults to Assembly.GetExecutingAssembly if left unspecified. We look through each assembly for types implementing IFacilityStartupTask, IContainerStartupTask, and IStartupTask and register them against the appropriate interface. (Facilities are Windsor’s primary extension mechanism. You can use facilities to implement everything from automatic transaction management to logging to array parameter resolution and more.) Next, we need to execute each of the startup tasks:
private void ExecuteFacilityStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IFacilityStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute(container));}private void ExecuteContainerStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IContainerStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute(container));}private void ExecuteStartupTasks() {    var tasks = container.ResolveAll&amp;lt;IStartupTask&amp;gt;();    tasks.ForEach(task =&amp;gt; task.Execute());}

Note that IFacilityStartupTask|IContainerStartupTask.Execute both take an IWindsorContainer, as their purpose is to configure the container. IStartupTask.Execute is to perform other types of initialization once the container is ready to be used and therefore doesn’t accept an IWindsorContainer.
The individual startup tasks are small and self-contained. For example, take a look at the ServiceRegistration class, which is responsible for registering application-related services:
public class ServicesRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            AllTypes.FromAssembly(Assembly.GetExecutingAssembly())                .Where(x =&amp;gt; x.Namespace.StartsWith("ScrewTurn.Wiki.Services"))                .WithService.FirstInterface(),            Component.For&amp;lt;IAclEvaluator&amp;gt;().ImplementedBy&amp;lt;AclEvaluator&amp;gt;()        );    }}

You can see the convention responsible for registering all services in the ScrewTurn.Wiki.Services namespace. There is also the extra configuration for the AclEvaluator. If we choose to combine the AclEngine project into Core, we could eliminate the extra configuration step for AclEvaluator.
We have a completely separate and independent IContainerStartupTask for Host and Provider registration:
public class HostAndProviderRegistration : IContainerStartupTask {    public void Execute(IWindsorContainer container) {        container.Register(            Component.For&amp;lt;IHostV30&amp;gt;().ImplementedBy&amp;lt;Host&amp;gt;());        var ssp = ProviderLoader.LoadSettingsStorageProvider(            WebConfigurationManager.AppSettings["SettingsStorageProvider"]);        container.Register(            Component.For&amp;lt;ISettingsStorageProviderV30&amp;gt;().Instance(ssp));    }}

As we break apart the “God object” that is the Host, we can modify its container registration in one place without affecting the registration of the services. If we need to perform additional unrelated container configuration, we create another class that implements the IFacilityStartupTask or IContainerStartupTask without affecting other configuration that is already taking place.
To wrap up, let’s refactor StartupTools.Startup() into a IStartupTask where it belongs:
Conclusion
Although it is not initially obvious, the ScrewTurn Wiki codebase suffers from dependency problems. Tight coupling of implementation classes caused by singletons and static classes result in a morass of objects, which is difficult to refactor. Dependency cycles between objects result in sensitive constructor and method orderings, which can result in unexpected NullReferenceExceptions after apparently innocuous changes to the code.
In this article, we have made dependencies obvious by changing them into constructor parameters and using an IoC container to wire together the dependencies. Using convention-over-configuration approaches eases the introduction of new functionality, without requiring explicit configuration. We have introduced a reusable ApplicationBootstrapper, whereby new startup tasks can be added as the application grows without modifying existing code. The resulting codebase should be more flexible and maintainable over time.
Other videos from this article

    Overview 
    Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee424155.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Refactoring/</link><pubDate>Tue, 01 Sep 2009 00:10:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.mp4</guid><evnet:views>4561</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/487028/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>The constructor signature for AuthorizationChecker now looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider,     IAuthTools authTools, IAclEvaluator aclEvaluator) { ... }   &lt;/pre&gt;
&lt;br /&gt;
We can clearly see that AuthorizationChecker depends on implementations of ISettingsStorageProviderV30, IAuthTools, and IAclEvalator, but we are not concerned with the actual implementations. This is the dependency inversion principle at work.</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.mp4" expression="full" duration="896" fileSize="27337695" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.mp3" expression="full" duration="896" fileSize="7171341" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.mp4" expression="full" duration="896" fileSize="27337695" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.wma" expression="full" duration="896" fileSize="7259631" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.wmv" expression="full" duration="896" fileSize="43586123" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_2MB_ch9.wmv" expression="full" duration="896" fileSize="35996878" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_Zune_ch9.wmv" expression="full" duration="896" fileSize="27442051" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_512_ch9.png" expression="full" duration="896" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/8/2/0/7/8/4/RefactoringStartupTools_ch9.mp4" length="27337695" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Refactoring/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/487028/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>Extreme ASP.NET Makeover: Disentangling Our Tangled Web-Overview - Overview</title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_85_ch9.png" border="0" /&gt;&lt;p&gt;We’re now on the eighth installment of Extreme ASP.NET Makeover. In part 7, we examined the singleton pattern and refactored away the AuthChecker singleton. AuthorizationServices, which previously used the AuthChecker singleton, now depends on the IAuthorizationChecker interface and simply creates an instance of the AuthorizationChecker class in its constructor by calling the new operator. In this intallment, we will discuss better ways to manage dependencies in our applications using an inversion of control container. If you are not familiar with inversion of control containers or the related concepts of dependency inversion and dependency injection, take some time to read James’ article on those topics from the March 2008 issue of &lt;i&gt;MSDN Magazine&lt;/i&gt;, &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc337885.aspx"&gt;“Loosen Up: Tame Your Software Dependencies for More Flexible Apps.”&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;The Tangled Web we Weave&lt;/h2&gt;
&lt;p&gt;Let’s take a closer look at AuthorizationServices. AuthorizationServices depends on IAuthorizationChecker, which is implemented by AuthorizationChecker. In turn, AuthorizationChecker depends on Settings to retrieve the configured ISettingsStorageProviderV30, which can be a SettingsStorageProvider, SqlSettingsStorageProvider, or other implementation. Now, SettingsStorageProvider depends on IHostV30 and its default implementation by Host. Host is a “God object” in ScrewTurn Wiki. According to Wikipedia, “a &lt;a href="http://en.wikipedia.org/wiki/God_object"&gt;God object&lt;/a&gt; is an object that &lt;i&gt;knows too much&lt;/i&gt; or &lt;i&gt; does too much&lt;/i&gt;.” A God object is a software anti-pattern.&lt;/p&gt;
&lt;p&gt;Host is a coordinator of a wide variety of unrelated activities in ScrewTurn. It handles everything from retrieving settings values to sending emails to handling backups to finding users, Wiki pages, namespaces, categories, and more. &lt;/p&gt;
&lt;p&gt;Many of these responsibilities are delegated to sub-objects, and Host only acts as the coordinator of these services. This is better than having all that functionality actually coded in Host itself. Host does still present a problem in that its delicate coordination of all the other objects in the system, especially during application startup, means that it is difficult to refactor the overall system. Moving startup code from one class to another causes breakages as the ordering of construction is slightly changed and previously working code throws NullReferenceExceptions as dependencies are unexpectedly null due to construction orderings.&lt;/p&gt;
&lt;p&gt;Let’s take a look at Host’s constructor:&lt;/p&gt;
&lt;pre&gt;public Host() {    customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;In its constructor, Host creates a single Dictionary. There is no indication that Host has a dependency problem. Host’s tangled web of dependencies is hidden due to its overuse of Singletons and static helper classes. For example, let’s take a look at a few Host methods:&lt;/p&gt;
&lt;pre&gt;public UserInfo[] GetUsers() {     return Users.Instance.GetUsers().ToArray();}public PageContent GetPageContent(PageInfo page) {    return Content.GetPageContent(page, true);}public string Format(string raw) {    return Formatter.Format(raw, FormattingContext.Unknown, null);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Note the use of the Users singleton and the static Content an Formatter classes in the above code. Without actually looking at Host’s implementation code, there is no way to tell that it depends on these other classes. To make matters even more complicated, Users (and other dependent classes) depend on Host! If constructors aren’t run in the correct order and before certain methods are called, NullReferenceExceptions will be your reward. All of the construction logic is carefully orchestrated by StartupTools, which is responsible for constructing and initializing all singletons within the application in the correct order.&lt;/p&gt;
&lt;h2&gt;Seeking Salvation&lt;/h2&gt;
&lt;p&gt;God objects lead us down a road unto madness. Host’s dependencies are so tangled and interdependent that the result is only somewhat better than a single, monolithic object. So how do we chart a course back to sanity?&lt;/p&gt;
&lt;p&gt;Dependencies in software are not fundamentally the problem here. Without dependencies, we wouldn’t be able to write much more than “Hello, World!”-style applications. (Even a simple application like Hello, World!  requires dependencies on System.Console and System.String, as well as the CLR.) The problem is unchecked and unfettered dependencies between objects that do not need to know about each other. Before we can solve the problem of unnecessary dependencies, we need to make those dependencies obvious. How can we construct our classes/objects so that their dependencies are obvious? Make dependencies apparent by declaring them in the classes constructor. For example, let’s look at AuthorizationServices’ constructor:&lt;/p&gt;
&lt;pre&gt;public AuthorizationServices(IAuthorizationChecker authorizationChecker) {    this.authorizationChecker = authorizationChecker;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Simply by looking at the constructor’s signature, we can tell that AuthorizationServices requires an IAuthorizationChecker to perform its work. (You probably already knew that because we implemented it in part 7.) The concrete implementation of IAuthorizationChecker is AuthorizationChecker:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker() {    settingsProvider = Settings.Instance.Provider;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Notice that you don’t know that AuthorizationChecker depends on the static Settings class. You have to read AuthorizationChecker’s constructor implementation to figure this out. While not hard, it is not immediately obvious that AuthorizationChecker depends on ISettingsStorageProviderV30, which is the type return by the Provider property. How can we make this more obvious? By declaring our intent in the constructor parameters, like so:&lt;/p&gt;
&lt;pre&gt;public AuthorizationChecker() : this(Settings.Instance.Provider) {}public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider) {    if(settingsProvider == null)        throw new ArgumentNullException("settingsProvider");    this.settingsProvider = settingsProvider;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Our other code depends on the parameterless constructor. We will leave it in place for now and chain to an overloaded constructor that takes a ISettingsStorageProviderV30. Our dependency on ISettingsStorageProviderV30 has now been made obvious.&lt;/p&gt;
&lt;p&gt;We are not out of the proverbial woods yet. Other dependencies are lurking within AuthorizationChecker, namely the static classes AuthTools and AclEvaluator. We can make them obvious dependencies by changing them from static classes to instances and moving their initialization to the constructor.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Overview/"&gt;Overview&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Refactoring/"&gt;Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee424155.aspx"&gt;http://msdn.microsoft.com/magazine/ee424155.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/487027/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Overview/</comments><itunes:summary>We’re now on the eighth installment of Extreme ASP.NET Makeover. In part 7, we examined the singleton pattern and refactored away the AuthChecker singleton. AuthorizationServices, which previously used the AuthChecker singleton, now depends on the IAuthorizationChecker interface and simply creates an instance of the AuthorizationChecker class in its constructor by calling the new operator. In this intallment, we will discuss better ways to manage dependencies in our applications using an inversion of control container. If you are not familiar with inversion of control containers or the related concepts of dependency inversion and dependency injection, take some time to read James’ article on those topics from the March 2008 issue of MSDN Magazine, “Loosen Up: Tame Your Software Dependencies for More Flexible Apps.”
The Tangled Web we Weave
Let’s take a closer look at AuthorizationServices. AuthorizationServices depends on IAuthorizationChecker, which is implemented by AuthorizationChecker. In turn, AuthorizationChecker depends on Settings to retrieve the configured ISettingsStorageProviderV30, which can be a SettingsStorageProvider, SqlSettingsStorageProvider, or other implementation. Now, SettingsStorageProvider depends on IHostV30 and its default implementation by Host. Host is a “God object” in ScrewTurn Wiki. According to Wikipedia, “a God object is an object that knows too much or  does too much.” A God object is a software anti-pattern.
Host is a coordinator of a wide variety of unrelated activities in ScrewTurn. It handles everything from retrieving settings values to sending emails to handling backups to finding users, Wiki pages, namespaces, categories, and more. 
Many of these responsibilities are delegated to sub-objects, and Host only acts as the coordinator of these services. This is better than having all that functionality actually coded in Host itself. Host does still present a problem in that its delicate coordination of all the other objects in the system, especially during application startup, means that it is difficult to refactor the overall system. Moving startup code from one class to another causes breakages as the ordering of construction is slightly changed and previously working code throws NullReferenceExceptions as dependencies are unexpectedly null due to construction orderings.
Let’s take a look at Host’s constructor:
public Host() {    customSpecialTags = new Dictionary&amp;lt;string, CustomToolbarItem&amp;gt;(5);}

In its constructor, Host creates a single Dictionary. There is no indication that Host has a dependency problem. Host’s tangled web of dependencies is hidden due to its overuse of Singletons and static helper classes. For example, let’s take a look at a few Host methods:
public UserInfo[] GetUsers() {     return Users.Instance.GetUsers().ToArray();}public PageContent GetPageContent(PageInfo page) {    return Content.GetPageContent(page, true);}public string Format(string raw) {    return Formatter.Format(raw, FormattingContext.Unknown, null);}

Note the use of the Users singleton and the static Content an Formatter classes in the above code. Without actually looking at Host’s implementation code, there is no way to tell that it depends on these other classes. To make matters even more complicated, Users (and other dependent classes) depend on Host! If constructors aren’t run in the correct order and before certain methods are called, NullReferenceExceptions will be your reward. All of the construction logic is carefully orchestrated by StartupTools, which is responsible for constructing and initializing all singletons within the application in the correct order.
Seeking Salvation
God objects lead us down a road unto madness. Host’s dependencies are so tangled and interdependent that the result is only somewhat better than a single, monolithic object. So how do we chart a course back to sanity?
Dependencies in software are not fundamentally the problem here. Without dependencies, we wouldn’t be able to write much more than “Hello, World!”-style applications. (Even a simple application like Hello, World!  requires dependencies on System.Console and System.String, as well as the CLR.) The problem is unchecked and unfettered dependencies between objects that do not need to know about each other. Before we can solve the problem of unnecessary dependencies, we need to make those dependencies obvious. How can we construct our classes/objects so that their dependencies are obvious? Make dependencies apparent by declaring them in the classes constructor. For example, let’s look at AuthorizationServices’ constructor:
public AuthorizationServices(IAuthorizationChecker authorizationChecker) {    this.authorizationChecker = authorizationChecker;}

Simply by looking at the constructor’s signature, we can tell that AuthorizationServices requires an IAuthorizationChecker to perform its work. (You probably already knew that because we implemented it in part 7.) The concrete implementation of IAuthorizationChecker is AuthorizationChecker:
public AuthorizationChecker() {    settingsProvider = Settings.Instance.Provider;}

Notice that you don’t know that AuthorizationChecker depends on the static Settings class. You have to read AuthorizationChecker’s constructor implementation to figure this out. While not hard, it is not immediately obvious that AuthorizationChecker depends on ISettingsStorageProviderV30, which is the type return by the Provider property. How can we make this more obvious? By declaring our intent in the constructor parameters, like so:
public AuthorizationChecker() : this(Settings.Instance.Provider) {}public AuthorizationChecker(ISettingsStorageProviderV30 settingsProvider) {    if(settingsProvider == null)        throw new ArgumentNullException("settingsProvider");    this.settingsProvider = settingsProvider;}

Our other code depends on the parameterless constructor. We will leave it in place for now and chain to an overloaded constructor that takes a ISettingsStorageProviderV30. Our dependency on ISettingsStorageProviderV30 has now been made obvious.
We are not out of the proverbial woods yet. Other dependencies are lurking within AuthorizationChecker, namely the static classes AuthTools and AclEvaluator. We can make them obvious dependencies by changing them from static classes to instances and moving their initialization to the constructor.
Other videos from this article

    Overview 
    Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee424155.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Overview/</link><pubDate>Tue, 01 Sep 2009 00:10:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.mp4</guid><evnet:views>4657</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/487027/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>We’re now on the eighth installment of Extreme ASP.NET Makeover. In part 7, we examined the singleton pattern and refactored away the AuthChecker singleton. AuthorizationServices, which previously used the AuthChecker singleton, now depends on the IAuthorizationChecker interface and simply creates an instance of the AuthorizationChecker class in its constructor by calling the new operator. In this intallment, we will discuss better ways to manage dependencies in our applications using an inversion of control container. If you are not familiar with inversion of control containers or the related concepts of dependency inversion and dependency injection, take some time to read James’ article on those topics from the March 2008 issue of MSDN Magazine, “Loosen Up: Tame Your Software Dependencies for More Flexible Apps.”</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.mp4" expression="full" duration="585" fileSize="19350270" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.mp3" expression="full" duration="585" fileSize="4683433" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.mp4" expression="full" duration="585" fileSize="19350270" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.wma" expression="full" duration="585" fileSize="4745289" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.wmv" expression="full" duration="585" fileSize="34717775" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_2MB_ch9.wmv" expression="full" duration="585" fileSize="30333124" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_Zune_ch9.wmv" expression="full" duration="585" fileSize="19469703" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_512_ch9.png" expression="full" duration="585" type="image/jpeg" medium="image" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/7/2/0/7/8/4/RefactoringDependenciesIntoTheConstructor_ch9.mp4" length="19350270" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Disentangling-Our-Tangled-Web-Overview-Overview/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/487027/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>ToolShed Tooltip #22 - Channel9 and the Tool Shed ... A Treasure Chest of Resources </title><description>&lt;img src="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_85_ch9.png" border="0" /&gt;&lt;p&gt;This Tool Shed Tooltip is about a very valuable resource for all developers... Channel9. Do you know there are other Microsoft communities linked to Channel9 for &lt;a href="http://www.asp.net/" target="_blank"&gt;ASP.NET&lt;/a&gt;, &lt;a href="http://silverlight.net/default.aspx" target="_blank"&gt;Silverlight&lt;/a&gt;, &lt;a href="http://www.iis.net/" target="_blank"&gt;IIS&lt;/a&gt;, &lt;a href="http://visitmix.com/" target="_blank"&gt;Mix&lt;/a&gt;, &lt;a href="http://edge.technet.com/" target="_blank"&gt;TechNet Edge &lt;/a&gt;and more? Do you know... &lt;strong&gt;not&lt;/strong&gt; every video posted to the channel9 site makes it to the home page? How do you find all of the videos? Do you know you can download a video in many different formats from Zune to High Def for offline viewing?  Do you know about the upcoming enhancements to Channel 9? Do you know you can rate videos and provide much wanted feedback? Did you know there is a &lt;a href="http://channel9.msdn.com/toolshed" target="_blank"&gt;channel9 toolshed site&lt;/a&gt; with links to all of the resources covered in the TV Shows as well as a &lt;a href="http://code.msdn.com/toolshed" title="Know The Code" target="_blank"&gt;toolshed code site&lt;/a&gt;? Watch this video to learn answers to these questions and many other tips and tricks to optimize your resource experience. &lt;br /&gt;
&lt;br /&gt;
This clip was originally filmed as part of &lt;a href="http://channel9.msdn.com/shows/toolshed/Show-Episode-4-Its-All-About-The-Tools-TV-Show/" target="_blank"&gt;Episode 4&lt;/a&gt; of It's All About The Tools, but it is &lt;b&gt;not&lt;/b&gt; &lt;b&gt;included&lt;/b&gt; in the final version. So, &lt;b&gt;&lt;span&gt;this is never seen before footage&lt;/span&gt;&lt;/b&gt;! This was presented in front of a live audience. And even though it was a roomful of Niners... each person I talked to after the event, still walked away learning something. Hopefully you will too!&lt;br /&gt;
&lt;br /&gt;
The show is hosted by &lt;a href="http://www.russtoolshed.net/" title="Tool Shed Blog" target="_blank"&gt;Russ Fustino &lt;/a&gt;and Co-Host &lt;a href="http://www.vbnetexpert.com/" title="MVP Stan Schultes" target="_blank"&gt;Stan Schultes.&lt;/a&gt; Download code, ppt and demo script from &lt;a href="http://code.msdn.com/toolshed" target="_blank"&gt;http://code.msdn.com/toolshed&lt;/a&gt; for all episodes. Also, use the links on &lt;a href="http://channel9.msdn.com/toolshed"&gt;http://channel9.msdn.com/toolshed&lt;/a&gt; to download tools. Finally, check out some more great videos on the Developer Evangelist East site: &lt;a href="http://channel9.msdn.com/dpeeast" target="_blank"&gt;http://channel9.msdn.com/dpeeast&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/486539/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/shows/toolshed/ToolShed-Tooltip-22-Channel9-and-the-Tool-Shed--A-Treasure-Chest-of-Resources/</comments><itunes:summary>This Tool Shed Tooltip is about a very valuable resource for all developers... Channel9. Do you know there are other Microsoft communities linked to Channel9 for ASP.NET, Silverlight, IIS, Mix, TechNet Edge and more? Do you know... not every video posted to the channel9 site makes it to the home page? How do you find all of the videos? Do you know you can download a video in many different formats from Zune to High Def for offline viewing?  Do you know about the upcoming enhancements to Channel 9? Do you know you can rate videos and provide much wanted feedback? Did you know there is a channel9 toolshed site with links to all of the resources covered in the TV Shows as well as a toolshed code site? Watch this video to learn answers to these questions and many other tips and tricks to optimize your resource experience. 

This clip was originally filmed as part of Episode 4 of It's All About The Tools, but it is not included in the final version. So, this is never seen before footage! This was presented in front of a live audience. And even though it was a roomful of Niners... each person I talked to after the event, still walked away learning something. Hopefully you will too!

The show is hosted by Russ Fustino and Co-Host Stan Schultes. Download code, ppt and demo script from http://code.msdn.com/toolshed for all episodes. Also, use the links on http://channel9.msdn.com/toolshed to download tools. Finally, check out some more great videos on the Developer Evangelist East site: http://channel9.msdn.com/dpeeast</itunes:summary><link>http://channel9.msdn.com/shows/toolshed/ToolShed-Tooltip-22-Channel9-and-the-Tool-Shed--A-Treasure-Chest-of-Resources/</link><pubDate>Mon, 24 Aug 2009 22:49:00 GMT</pubDate><guid isPermaLink="false">http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.mp4</guid><evnet:views>37365</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/486539/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>This Tool Shed Tooltip is about a very valuable resource for all developers... Channel9. Do you know there are other Microsoft communities linked to Channel9 for ASP.NET, Silverlight, IIS, Mix, TechNet Edge and more? Do you know... not every video posted to the channel9 site makes it to the home page? How do you find all of the videos? Do you know you can download a video in many different formats from Zune to High Def for offline viewing?  Do you know about the upcoming enhancements to Channel 9? Do you know you can rate videos and provide much wanted feedback? Did you know there is…</evnet:previewtext><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_320_ch9.png" height="240" width="320" /><media:thumbnail url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_85_ch9.png" height="64" width="85" /><media:group><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.mp4" expression="full" duration="644" fileSize="28238005" type="video/mp4" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.mp3" expression="full" duration="644" fileSize="5156963" type="audio/mp3" medium="audio" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.mp4" expression="full" duration="644" fileSize="28238005" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.wma" expression="full" duration="644" fileSize="5225929" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.wmv" expression="full" duration="644" fileSize="50014601" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_2MB_ch9.wmv" expression="full" duration="644" fileSize="52114721" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_Zune_ch9.wmv" expression="full" duration="644" fileSize="28574529" type="video/x-ms-wmv" medium="video" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_512_ch9.png" expression="full" duration="644" type="image/jpeg" medium="image" /><media:content url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_2MB_ch9.wmv" expression="full" duration="644" fileSize="52114721" type="video/x-ms-asf" medium="video" /></media:group><enclosure url="http://ecn.channel9.msdn.com/o9/ch9/9/3/5/6/8/4/ToolShedTooltip0022_ch9.mp4" length="28238005" type="video/mp4" /><dc:creator>Russell Fustino</dc:creator><itunes:author>Russell Fustino</itunes:author><slash:comments>3</slash:comments><wfw:commentRss>http://channel9.msdn.com/shows/toolshed/ToolShed-Tooltip-22-Channel9-and-the-Tool-Shed--A-Treasure-Chest-of-Resources/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/486539/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>IIS</category><category>Mix</category><category>Silverlight</category><category>toolshed</category></item><item><title>Extreme ASP.NET Makeover: Singleton - Refactoring</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_small_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Death of a Singleton-Refactoring&lt;/h1&gt;
&lt;p&gt;Now that we have a new class, complete with functionality, we can start to refactor other parts of the application to use it instead of the AuthChecker singleton.  Like all the other refactorings we’ve done thus far in this article, it’s not that big of a deal.  As our example, we’re going to continue to refactor the AuthorizationServices class (see the &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee210417.aspx"&gt;previous Separation of Concerns article&lt;/a&gt; for the initial refactoring for this).  In AuthorizationServices, we want to eliminate the use of AuthChecker and, in its place, use an instance of AuthorizationChecker instead.&lt;/p&gt;
&lt;p&gt;To do this, we first need to create a module level variable that provides the same capabilities as the AuthChecker singleton.  Earlier in this article, we created an IAuthenticationChecker interface that worked to enforce this for us.  Now is another time that we can use it.  As you can see in the code below, we now have created an instance of the AuthenticationChecker and assigned it to the module level variable:&lt;/p&gt;
&lt;pre&gt;public class AuthorizationServices{    private IAuthorizationChecker _authenticationChecker;    public AuthorizationServices()    {        authorizationChecker = new AuthorizationChecker();    }    ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Now that we have a way to access the authentication checking code, we just need to replace the AuthChecker calls in the RetrieveCurrentStatusFor method with calls to the module level variable.  As an example of these changes, here is what the first one would look like:&lt;/p&gt;
&lt;pre&gt;CanView = _authorizationChecker.CheckActionForPage(currentPage,     Actions.ForPages.ReadPage, currentUsername, currentGroups),&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;With that we have our AuthorizationServices class refactored and we’ve finished the first full round of changes that are required to eliminate the AuthChecker singleton.  If we take a look at the usages of the AuthChecker singleton instance, we’ll see that there are still a large number of places that it is being used.&lt;/p&gt;
&lt;p&gt;Now that you’ve finished this first complete refactoring to use the new AuthorizationChecker class, you’ve also reached the first logical checkpoint in your refactoring exercise.  From here you can choose when you want to move from the AuthChecker singleton to an AuthorizationChecker instance class in any of the other places that AuthChecker is being used.  As you incrementally move through your changes from AuthChecker to AuthorizationChecker, you get closer and closer to the next step in this refactoring: deleting the AuthChecker singleton.&lt;/p&gt;
&lt;p&gt;Once you have all of the usages of AuthChecker replaced with the AuthorizationChecker class you’re almost ready to remove the AuthChecker class from your code base.  Before we can do that, remember that we had the new AuthorizationChecker class delegating execution to the AuthChecker singleton.  To be able to get rid of AuthChecker completely, we need to move its logic into the new AuthorizationChecker class.  There are a couple of small things that we need to address in this refactoring, such as adding using statements.   &lt;/p&gt;
&lt;p&gt;The main change we need is to address the code’s need for an ISettingsStorageProviderV30 typed object.  If we look into how that object is being passed into the AuthChecker singleton, we see that it’s actually being provided from another singleton named Settings:&lt;/p&gt;
&lt;pre&gt;AuthChecker.Instance = new AuthChecker(Settings.Instance.Provider);&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Since this value is coming from a singleton, we can easily add a module level variable to AuthorizationChecker that can be used throughout its methods.  Assigning that variable is as simple as what you see below.  Also note that we no longer need the module level AuthChecker variable since we’ve now moved all of the AuthChecker code into this class.  Since it’s not needed, we’ve removed it and the code related to it in the constructor:&lt;/p&gt;
&lt;pre&gt;private ISettingsStorageProviderV30 _settingsProvider; public AuthorizationChecker(){    _settingsProvider = Settings.Instance.Provider;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The result of this final refactoring is that the public methods on AuthChecker are no longer being executed anywhere in the code base.  If you were to do a Find Usages on AuthChecker, you’ll see that the only place it exists is in the StartupTools class where it was being initialized.  Since it’s not being used anywhere, there’s no need to initialize it, so we’ll just delete that line of code.  Now we’re completely free of any use of AuthChecker, so we can delete the class from the project.  With that, you’re free of your singleton past...or at least one part of it.&lt;/p&gt;
&lt;h1&gt;I realized what a ridiculous lie my whole life has been...&lt;/h1&gt;
&lt;p&gt;We’ve spent some quality time together on this article and have weaned you from a dependence on singletons in your code base.  Singletons often are seen as the “easy” way to code.  Just because you don’t have to “new up” a class to make use of its functionality, doesn’t mean that you’re not imposing a debt on your code base.  While singletons seem like the route of least friction at first, you quickly find out that they’re nothing more than a mirage on the way to software development bliss.  You see the ease of development that they offer, but every time that you move closer the goal is still just as far away as it was before.&lt;/p&gt;
&lt;p&gt;Unless you truly need to ensure that one, and only one, instance of an object exists per application lifecycle, then you should be working to refactor singletons out of your code base.  Hopefully, the techniques in this article have pointed you in the right direction to be able to do that.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/"&gt;Demoing Different Singleton Implementations&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/"&gt;How Singletons Affect Testability&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/"&gt;Looking At AuthChecker&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/"&gt;Walkthrough Of The Entire Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee343987.aspx"&gt;http://msdn.microsoft.com/magazine/ee343987.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/482733/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/</comments><itunes:summary>Extreme ASP.NET Makeover: Death of a Singleton-Refactoring
Now that we have a new class, complete with functionality, we can start to refactor other parts of the application to use it instead of the AuthChecker singleton.  Like all the other refactorings we’ve done thus far in this article, it’s not that big of a deal.  As our example, we’re going to continue to refactor the AuthorizationServices class (see the previous Separation of Concerns article for the initial refactoring for this).  In AuthorizationServices, we want to eliminate the use of AuthChecker and, in its place, use an instance of AuthorizationChecker instead.
To do this, we first need to create a module level variable that provides the same capabilities as the AuthChecker singleton.  Earlier in this article, we created an IAuthenticationChecker interface that worked to enforce this for us.  Now is another time that we can use it.  As you can see in the code below, we now have created an instance of the AuthenticationChecker and assigned it to the module level variable:
public class AuthorizationServices{    private IAuthorizationChecker _authenticationChecker;    public AuthorizationServices()    {        authorizationChecker = new AuthorizationChecker();    }    ...}

Now that we have a way to access the authentication checking code, we just need to replace the AuthChecker calls in the RetrieveCurrentStatusFor method with calls to the module level variable.  As an example of these changes, here is what the first one would look like:
CanView = _authorizationChecker.CheckActionForPage(currentPage,     Actions.ForPages.ReadPage, currentUsername, currentGroups),

With that we have our AuthorizationServices class refactored and we’ve finished the first full round of changes that are required to eliminate the AuthChecker singleton.  If we take a look at the usages of the AuthChecker singleton instance, we’ll see that there are still a large number of places that it is being used.
Now that you’ve finished this first complete refactoring to use the new AuthorizationChecker class, you’ve also reached the first logical checkpoint in your refactoring exercise.  From here you can choose when you want to move from the AuthChecker singleton to an AuthorizationChecker instance class in any of the other places that AuthChecker is being used.  As you incrementally move through your changes from AuthChecker to AuthorizationChecker, you get closer and closer to the next step in this refactoring: deleting the AuthChecker singleton.
Once you have all of the usages of AuthChecker replaced with the AuthorizationChecker class you’re almost ready to remove the AuthChecker class from your code base.  Before we can do that, remember that we had the new AuthorizationChecker class delegating execution to the AuthChecker singleton.  To be able to get rid of AuthChecker completely, we need to move its logic into the new AuthorizationChecker class.  There are a couple of small things that we need to address in this refactoring, such as adding using statements.   
The main change we need is to address the code’s need for an ISettingsStorageProviderV30 typed object.  If we look into how that object is being passed into the AuthChecker singleton, we see that it’s actually being provided from another singleton named Settings:
AuthChecker.Instance = new AuthChecker(Settings.Instance.Provider);

 
Since this value is coming from a singleton, we can easily add a module level variable to AuthorizationChecker that can be used throughout its methods.  Assigning that variable is as simple as what you see below.  Also note that we no longer need the module level AuthChecker variable since we’ve now moved all of the AuthChecker code into this class.  Since it’s not needed, we’ve removed it and the code related to it in the constructor:
private ISettingsStorageProviderV30 _settingsProvider; public AuthorizationChecker(){    _settingsProvider = Settings.Instance.Provider;}

The result of this final refactoring is that the public methods on AuthChecker are no longer being executed anywhere in the code base.  If you were to do a Find Usages on AuthChecker, you’ll see that the only place it exists is in the StartupTools class where it was being initialized.  Since it’s not being used anywhere, there’s no need to initialize it, so we’ll just delete that line of code.  Now we’re completely free of any use of AuthChecker, so we can delete the class from the project.  With that, you’re free of your singleton past...or at least one part of it.
I realized what a ridiculous lie my whole life has been...
We’ve spent some quality time together on this article and have weaned you from a dependence on singletons in your code base.  Singletons often are seen as the “easy” way to code.  Just because you don’t have to “new up” a class to make use of its functionality, doesn’t mean that you’re not imposing a debt on your code base.  While singletons seem like the route of least friction at first, you quickly find out that they’re nothing more than a mirage on the way to software development bliss.  You see the ease of development that they offer, but every time that you move closer the goal is still just as far away as it was before.
Unless you truly need to ensure that one, and only one, instance of an object exists per application lifecycle, then you should be working to refactor singletons out of your code base.  Hopefully, the techniques in this article have pointed you in the right direction to be able to do that.
Other videos from this article

    Demoing Different Singleton Implementations 
    How Singletons Affect Testability 
    Looking At AuthChecker 
    Walkthrough Of The Entire Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee343987.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/</link><pubDate>Tue, 04 Aug 2009 23:57:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.mp4</guid><evnet:views>5639</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/482733/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Now that we have a new class, complete with functionality, we can start to refactor other parts of the application to use it instead of the AuthChecker singleton.  Like all the other refactorings we’ve done thus far in this article, it’s not that big of a deal.  As our example, we’re going to continue to refactor the AuthorizationServices class (see the previous Separation of Concerns article for the initial refactoring for this).  In AuthorizationServices, we want to eliminate the use of AuthChecker and, in its place, use an instance of AuthorizationChecker instead.</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.mp4" expression="full" duration="455" fileSize="13461933" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.mp3" expression="full" duration="455" fileSize="3643708" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.mp4" expression="full" duration="455" fileSize="13461933" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.wma" expression="full" duration="455" fileSize="3687875" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_2MB_ch9.wmv" expression="full" duration="455" fileSize="16059824" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_2MB_ch9.wmv" expression="full" duration="455" fileSize="16059824" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_Zune_ch9.wmv" expression="full" duration="455" fileSize="12571877" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/3/7/2/8/4/WalkthroughOfTheEntireRefactoring_ch9.mp4" length="13461933" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/482733/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>Extreme ASP.NET Makeover: Singleton - AuthChecker Class</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_small_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Death of a Singleton-AuthChecker Class&lt;/h1&gt;
&lt;h1&gt;I’ve Got Some Seeds, Right Away&lt;/h1&gt;
&lt;p&gt;So where should we start?  How about the AuthChecker class, since that’s what we’ve discussed through the first part of this article.  Earlier, we decided that there was no reason for it to continue to be a singleton, since there was no compelling reason for one, and only one, instance of it to exist for the life of the application.&lt;/p&gt;
&lt;p&gt;The process that we’re going to go through will see us move from using the existing AuthChecker class to using instances of an AuthorizationChecker class.  Once we’ve made the transition from AuthChecker to AuthorizationChecker, we will delete the AuthChecker Singleton from our codebase.&lt;/p&gt;
&lt;p&gt;The first challenge that we have to face in this process is how do we create a new class (AuthorizationChecker) which we can guarantee to expose the same functionality as the original (AuthChecker) class.  There are two reasonable options for this: abstract base class and interface.  Abstract base class is a good solution, if we were going to need to use the same AuthChecker functionality in multiple class implementation for the distant future.  In this case though, we’ve already determined that we’re going to be deleting the AuthChecker Singleton implementation once we’ve completed our refactoring.  As a result, using Interfaces makes more sense.&lt;/p&gt;
&lt;p&gt;That makes our first step in the process to extract an interface from the AuthChecker class.  As you can see below, it’s really a simple interface, called IAuthorizationChecker, that defines the four publically exposed methods on the AuthChecker class:&lt;/p&gt;
&lt;pre&gt;public interface IAuthenticationChecker{    bool CheckActionForGlobals(string action, string currentUser,        string[] groups);    bool CheckActionForNamespace(NamespaceInfo nspace, string action,        string currentUser, string[] groups);    bool CheckActionForPage(PageInfo page, string action,        string currentUser, string[] groups);    bool CheckActionForDirectory(IFilesStorageProviderV30 provider,         string directory, string action, string currentUser, string[] groups);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Now that we have that interface we need to get the AuthChecker to implement it.  This is pretty easy, but has a couple of small twists.  Because we’re applying the interface to a Singleton class, we also have to ensure that the .Instance property is returning a type of the IAuthenticationChecker interface.  To get the code to compile we also have to change the type of the properties underlying module level variable so that it too is of type IAuthorizationChecker:&lt;/p&gt;
&lt;pre&gt;public class AuthorizationChecker : IAuthorizationChecker{    public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForPage(PageInfo page, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider, string directory,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Interestingly, this is the last of the changes that you’ll have to make to AuthChecker before you delete it from the project.&lt;/p&gt;
&lt;p&gt;Now that we’ve established how calling code should expect us to behave (via the IAuthorizationChecker interface), we can go ahead and write a new class that meets that expectation.  In this case we’re going to call the class AuthorizationChecker and we’ll make it implement the interface.  The result, as shown in &lt;b&gt;Figure 6&lt;/b&gt;, is a class with the same four public methods on it that the AuthChecker class has.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 6 Class With Four Public Methods&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class AuthorizationChecker : IAuthorizationChecker{    public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForPage(PageInfo page, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider,         string directory, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Now that our new AuthorizationChecker class has a basic shell, we need to get it working with the same functionality as the original AuthChecker singleton.   One of the key things when doing refactorings like this is to be able to do them incrementally.   Big-bang approaches can be successful, but rarely do you have the ability to impose the constraints, such as time and cost, on your project’s current needs.  Instead, we want to be able to nibble away at the refactoring as time permits and in a way that won’t affect the project.&lt;/p&gt;
&lt;p&gt;To do this, we’re going to take our new AuthenticationChecker class and simply pass through the calls to the original AuthChecker code.   This may seem like an extraneous step, but it’s one that is necessary to achieve the goal of refactoring little by little.  To make this happen, we need to get an instance of AuthChecker into the local scope of the newly created AuthenticationChecker class:&lt;/p&gt;
&lt;pre&gt;private IAuthorizationChecker _authChecker; public AuthorizationChecker(){    AuthChecker.Instance = new AuthChecker(Settings.Instance.Provider);    _authChecker = AuthChecker.Instance;}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Once we have the AuthChecker instance in place, we can have the methods in the class simply delegate execution to the existing methods in the AuthChecker class.  Like we said before, this may seem extraneous, but trust us, we’re going somewhere here, as shown in &lt;b&gt;Figure 7&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 7 Execution of Existing Methods in the AuthChecker Class&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public bool CheckActionForGlobals(string action, string currentUser,     string[] groups){    return _authChecker.CheckActionForGlobals(action, currentUser,        groups);} public bool CheckActionForNamespace(NamespaceInfo nspace,     string action, string currentUser, string[] groups){    return _authChecker.CheckActionForNamespace(nspace, action,         currentUser, groups);} public bool CheckActionForPage(PageInfo page, string action,     string currentUser, string[] groups){    return _authChecker.CheckActionForPage(page, action,         currentUser, groups);} public bool CheckActionForDirectory(IFilesStorageProviderV30 provider,     string directory, string action, string currentUser, string[] groups){    return _authChecker.CheckActionForDirectory(provider, directory,         action, currentUser, groups);}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;One of the key things to note with this approach is that we’ve maintained a single place of change for the code that is related to the AuthChecker/AuthorizationChecker functionality.  If we’re going to be tackling this refactoring over a period of time, this is key, since we can’t be confidently maintaining multiple pieces of code that represent the same functionality.  Don’t be fooled that the maintenance cost of this approach is zero.  If you were to change the arguments in the methods, you’d have multiple places to change, but, on a positive note, you’d get compile errors from that due to the use of an interface enforcing the publically exposed contract.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/"&gt;Demoing Different Singleton Implementations&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/"&gt;How Singletons Affect Testability&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/"&gt;Looking At AuthChecker&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/"&gt;Walkthrough Of The Entire Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee343987.aspx"&gt;http://msdn.microsoft.com/magazine/ee343987.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/482732/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/</comments><itunes:summary>Extreme ASP.NET Makeover: Death of a Singleton-AuthChecker Class
I’ve Got Some Seeds, Right Away
So where should we start?  How about the AuthChecker class, since that’s what we’ve discussed through the first part of this article.  Earlier, we decided that there was no reason for it to continue to be a singleton, since there was no compelling reason for one, and only one, instance of it to exist for the life of the application.
The process that we’re going to go through will see us move from using the existing AuthChecker class to using instances of an AuthorizationChecker class.  Once we’ve made the transition from AuthChecker to AuthorizationChecker, we will delete the AuthChecker Singleton from our codebase.
The first challenge that we have to face in this process is how do we create a new class (AuthorizationChecker) which we can guarantee to expose the same functionality as the original (AuthChecker) class.  There are two reasonable options for this: abstract base class and interface.  Abstract base class is a good solution, if we were going to need to use the same AuthChecker functionality in multiple class implementation for the distant future.  In this case though, we’ve already determined that we’re going to be deleting the AuthChecker Singleton implementation once we’ve completed our refactoring.  As a result, using Interfaces makes more sense.
That makes our first step in the process to extract an interface from the AuthChecker class.  As you can see below, it’s really a simple interface, called IAuthorizationChecker, that defines the four publically exposed methods on the AuthChecker class:
public interface IAuthenticationChecker{    bool CheckActionForGlobals(string action, string currentUser,        string[] groups);    bool CheckActionForNamespace(NamespaceInfo nspace, string action,        string currentUser, string[] groups);    bool CheckActionForPage(PageInfo page, string action,        string currentUser, string[] groups);    bool CheckActionForDirectory(IFilesStorageProviderV30 provider,         string directory, string action, string currentUser, string[] groups);}

Now that we have that interface we need to get the AuthChecker to implement it.  This is pretty easy, but has a couple of small twists.  Because we’re applying the interface to a Singleton class, we also have to ensure that the .Instance property is returning a type of the IAuthenticationChecker interface.  To get the code to compile we also have to change the type of the properties underlying module level variable so that it too is of type IAuthorizationChecker:
public class AuthorizationChecker : IAuthorizationChecker{    public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForPage(PageInfo page, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider, string directory,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }}

Interestingly, this is the last of the changes that you’ll have to make to AuthChecker before you delete it from the project.
Now that we’ve established how calling code should expect us to behave (via the IAuthorizationChecker interface), we can go ahead and write a new class that meets that expectation.  In this case we’re going to call the class AuthorizationChecker and we’ll make it implement the interface.  The result, as shown in Figure 6, is a class with the same four public methods on it that the AuthChecker class has.
Figure 6 Class With Four Public Methods
public class AuthorizationChecker : IAuthorizationChecker{    public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForPage(PageInfo page, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider,         string directory, string action,         string currentUser, string[] groups)    {        throw new NotImplementedException();    }}

Now that our new AuthorizationChecker class has a basic shell, we need to get it working with the same functionality as the original AuthChecker singleton.   One of the key things when doing refactorings like this is to be able to do them incrementally.   Big-bang approaches can be successful, but rarely do you have the ability to impose the constraints, such as time and cost, on your project’s current needs.  Instead, we want to be able to nibble away at the refactoring as time permits and in a way that won’t affect the project.
To do this, we’re going to take our new AuthenticationChecker class and simply pass through the calls to the original AuthChecker code.   This may seem like an extraneous step, but it’s one that is necessary to achieve the goal of refactoring little by little.  To make this happen, we need to get an instance of AuthChecker into the local scope of the newly created AuthenticationChecker class:
private IAuthorizationChecker _authChecker; public AuthorizationChecker(){    AuthChecker.Instance = new AuthChecker(Settings.Instance.Provider);    _authChecker = AuthChecker.Instance;}

Once we have the AuthChecker instance in place, we can have the methods in the class simply delegate execution to the existing methods in the AuthChecker class.  Like we said before, this may seem extraneous, but trust us, we’re going somewhere here, as shown in Figure 7.
Figure 7 Execution of Existing Methods in the AuthChecker Class
public bool CheckActionForGlobals(string action, string currentUser,     string[] groups){    return _authChecker.CheckActionForGlobals(action, currentUser,        groups);} public bool CheckActionForNamespace(NamespaceInfo nspace,     string action, string currentUser, string[] groups){    return _authChecker.CheckActionForNamespace(nspace, action,         currentUser, groups);} public bool CheckActionForPage(PageInfo page, string action,     string currentUser, string[] groups){    return _authChecker.CheckActionForPage(page, action,         currentUser, groups);} public bool CheckActionForDirectory(IFilesStorageProviderV30 provider,     string directory, string action, string currentUser, string[] groups){    return _authChecker.CheckActionForDirectory(provider, directory,         action, currentUser, groups);}

One of the key things to note with this approach is that we’ve maintained a single place of change for the code that is related to the AuthChecker/AuthorizationChecker functionality.  If we’re going to be tackling this refactoring over a period of time, this is key, since we can’t be confidently maintaining multiple pieces of code that represent the same functionality.  Don’t be fooled that the maintenance cost of this approach is zero.  If you were to change the arguments in the methods, you’d have multiple places to change, but, on a positive note, you’d get compile errors from that due to the use of an interface enforcing the publically exposed contract.
Other videos from this article

    Demoing Different Singleton Implementations 
    How Singletons Affect Testability 
    Looking At AuthChecker 
    Walkthrough Of The Entire Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee343987.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/</link><pubDate>Tue, 04 Aug 2009 23:57:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.mp4</guid><evnet:views>5741</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/482732/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>So where should we start?  How about the AuthChecker class, since that’s what we’ve discussed through the first part of this article.  Earlier, we decided that there was no reason for it to continue to be a singleton, since there was no compelling reason for one, and only one, instance of it to exist for the life of the application.</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.mp4" expression="full" duration="93" fileSize="2705278" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.mp3" expression="full" duration="93" fileSize="752696" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.mp4" expression="full" duration="93" fileSize="2705278" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.wma" expression="full" duration="93" fileSize="773995" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_2MB_ch9.wmv" expression="full" duration="93" fileSize="2742502" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_2MB_ch9.wmv" expression="full" duration="93" fileSize="2742502" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_Zune_ch9.wmv" expression="full" duration="93" fileSize="2646809" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/2/3/7/2/8/4/LookingAtAuthChecker_ch9.mp4" length="2705278" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/482732/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>Extreme ASP.NET Makeover: Singleton - Testability</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_small_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Death of a Singleton-Testability&lt;/h1&gt;
&lt;h1&gt;He’s Liked, But He’s Not Well Liked&lt;/h1&gt;
&lt;p&gt;If the current code works, why do we need to get rid of the singleton? What harm is it doing? After all, there’s a reason the pattern has a name. It must be useful.&lt;/p&gt;
&lt;p&gt;We have a few issues with singletons. The easiest argument to make is that singletons make your code hard to test. If you make a call to a singleton in a class, then you must make sure the singleton is initialized whenever the test is run. If the singleton requires a connection to a database or the existence of a Web service, these must be configured prior to running the test. If you want reasons why this is a bad practice, look no further than our previous article on separation of concerns.&lt;/p&gt;
&lt;p&gt;This lack of testability isn’t the only problem. After all, there are ways (usually neither easy nor pleasant) to make singletons testable. Indeed, ScrewTurn uses one of them by exposing a public constructor. Let’s look more closely at the AuthChecker class we’ve been working with. Why is it a singleton class? Perhaps so that its members can be accessed throughout the site without having to create a new instance of it? Perhaps to save on resources by reducing object allocation and garbage collection? (This would almost certainly be a premature optimization.)&lt;/p&gt;
&lt;p&gt;Let’s look at the first public method on the class, CheckActionForGlobals. Where is this being used? If you trace its usages, you’ll find it is used in exactly three other classes: the AdminMaster master page and FileManager.ascx control (both in the WebApplication project) and the AuthorizationServices class in the Core project. (The latter is one of the refactorings we did in Part 6; originally, it was being called in Default.aspx in the WebApplication project.)&lt;/p&gt;
&lt;p&gt;So this globally accessible method is really only being used in three places. Doesn’t sound all that global to us. One could make an argument that each of these classes could just create an instance of the class instead. That would make them easier to test and less fragile overall.&lt;/p&gt;
&lt;p&gt;Of course, we’ve been cautiously selective in our example. CheckActionForGlobals is but one method in the AuthChecker singleton. If we look at all cases where we reference AuthChecker.Instance, we’ll find no less than 86 occurrences of it across 21 files.&lt;/p&gt;
&lt;p&gt;“Aha!” you say. “Doesn’t that contradict your argument that it’s not really being used globally?” “Pshaw!” say we! What it does is highlight another issue with singletons. The Instance variable is used in 21 files, yet CheckActionForGlobals is used in 3. Another method, CheckActionForDirectory, is used in 5, not including calls made from within the AuthChecker class itself.&lt;/p&gt;
&lt;p&gt;In short, our singleton has turned into a sort of catch-all bucket, a place to house disparate methods under the loosely-defined category of “authorization checking.” Granted, the AuthChecker class isn’t as messy as it could be, but the tendency with singleton classes is to make them more and more generic as you add “helper” methods to them. The ubiquitous Utils singleton often seen in many projects is a good example. Developers see a singleton and it’s just so darned tempting to drop a method in there rather than create a separate class with a more specific focus.&lt;/p&gt;
&lt;p&gt;The result of those temptations is that you find code bases that are littered with unnecessary singletons.  While they may seem innocuous at first, the problems we described earlier will start to haunt your project.  To help you with those existing Singletons, let’s look at how we can move through our code and remove them.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/"&gt;Demoing Different Singleton Implementations&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/"&gt;How Singletons Affect Testability&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/"&gt;Looking At AuthChecker&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/"&gt;Walkthrough Of The Entire Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee343987.aspx"&gt;http://msdn.microsoft.com/magazine/ee343987.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/482731/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/</comments><itunes:summary>Extreme ASP.NET Makeover: Death of a Singleton-Testability
He’s Liked, But He’s Not Well Liked
If the current code works, why do we need to get rid of the singleton? What harm is it doing? After all, there’s a reason the pattern has a name. It must be useful.
We have a few issues with singletons. The easiest argument to make is that singletons make your code hard to test. If you make a call to a singleton in a class, then you must make sure the singleton is initialized whenever the test is run. If the singleton requires a connection to a database or the existence of a Web service, these must be configured prior to running the test. If you want reasons why this is a bad practice, look no further than our previous article on separation of concerns.
This lack of testability isn’t the only problem. After all, there are ways (usually neither easy nor pleasant) to make singletons testable. Indeed, ScrewTurn uses one of them by exposing a public constructor. Let’s look more closely at the AuthChecker class we’ve been working with. Why is it a singleton class? Perhaps so that its members can be accessed throughout the site without having to create a new instance of it? Perhaps to save on resources by reducing object allocation and garbage collection? (This would almost certainly be a premature optimization.)
Let’s look at the first public method on the class, CheckActionForGlobals. Where is this being used? If you trace its usages, you’ll find it is used in exactly three other classes: the AdminMaster master page and FileManager.ascx control (both in the WebApplication project) and the AuthorizationServices class in the Core project. (The latter is one of the refactorings we did in Part 6; originally, it was being called in Default.aspx in the WebApplication project.)
So this globally accessible method is really only being used in three places. Doesn’t sound all that global to us. One could make an argument that each of these classes could just create an instance of the class instead. That would make them easier to test and less fragile overall.
Of course, we’ve been cautiously selective in our example. CheckActionForGlobals is but one method in the AuthChecker singleton. If we look at all cases where we reference AuthChecker.Instance, we’ll find no less than 86 occurrences of it across 21 files.
“Aha!” you say. “Doesn’t that contradict your argument that it’s not really being used globally?” “Pshaw!” say we! What it does is highlight another issue with singletons. The Instance variable is used in 21 files, yet CheckActionForGlobals is used in 3. Another method, CheckActionForDirectory, is used in 5, not including calls made from within the AuthChecker class itself.
In short, our singleton has turned into a sort of catch-all bucket, a place to house disparate methods under the loosely-defined category of “authorization checking.” Granted, the AuthChecker class isn’t as messy as it could be, but the tendency with singleton classes is to make them more and more generic as you add “helper” methods to them. The ubiquitous Utils singleton often seen in many projects is a good example. Developers see a singleton and it’s just so darned tempting to drop a method in there rather than create a separate class with a more specific focus.
The result of those temptations is that you find code bases that are littered with unnecessary singletons.  While they may seem innocuous at first, the problems we described earlier will start to haunt your project.  To help you with those existing Singletons, let’s look at how we can move through our code and remove them.
Other videos from this article

    Demoing Different Singleton Implementations 
    How Singletons Affect Testability 
    Looking At AuthChecker 
    Walkthrough Of The Entire Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee343987.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/</link><pubDate>Tue, 04 Aug 2009 23:57:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.mp4</guid><evnet:views>5938</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/482731/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>We have a few issues with singletons. The easiest argument to make is that singletons make your code hard to test. If you make a call to a singleton in a class, then you must make sure the singleton is initialized whenever the test is run. If the singleton requires a connection to a database or the existence of a Web service, these must be configured prior to running the test. If you want reasons why this is a bad practice, look no further than our previous article on separation of concerns.</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.mp4" expression="full" duration="504" fileSize="15747760" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.mp3" expression="full" duration="504" fileSize="4039933" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.mp4" expression="full" duration="504" fileSize="15747760" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.wma" expression="full" duration="504" fileSize="4090417" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_2MB_ch9.wmv" expression="full" duration="504" fileSize="19788520" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_2MB_ch9.wmv" expression="full" duration="504" fileSize="19788520" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_Zune_ch9.wmv" expression="full" duration="504" fileSize="14396569" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/1/3/7/2/8/4/HowSingletonsAffectTestability_ch9.mp4" length="15747760" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/482731/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>Extreme ASP.NET Makeover: Singleton - Overview</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_small_ch9.png" border="0" /&gt;&lt;h1&gt;Extreme ASP.NET Makeover: Death of a Singleton-Overview&lt;/h1&gt;
&lt;p&gt;Let’s review one of the changes we made to the code in part 6. In that discussion, we refactored the authorization checking into a separate class, AuthorizationServices. To do that, we moved a lot of code from the Page_Load method of our Default.aspx page into it. &lt;b&gt;Figure 1 &lt;/b&gt;shows an excerpt from the RetrieveCurrentStatusFor method.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 1 Excerpt from the RetrieveCurrentStatusFor Method&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;return new CurrentCapabilitiesStatus{    CanView = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ReadPage,        currentUsername, currentGroups),    CanDownloadAttachments = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.DownloadAttachments,        currentUsername, currentGroups),    CanSetPerms = AuthChecker.Instance.CheckActionForGlobals(        Actions.ForGlobals.ManagePermissions,        currentUsername, currentGroups),    CanAdmin = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ManagePage,        currentUsername, currentGroups),    CanViewDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ReadDiscussion,        currentUsername, currentGroups),    CanPostDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.PostDiscussion,        currentUsername, currentGroups),    CanManageDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ManageDiscussion,        currentUsername, currentGroups),    CanEdit = canEdit,    CanEditWithApproval = canEditWithApproval};&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Notice all the calls to AuthChecker.Instance. This is an example of the Singleton Design Pattern at work. We’ll define it now to get everyone on the same page.&lt;/p&gt;
&lt;h1&gt;There Can Be Only One&lt;/h1&gt;
&lt;p&gt;The defining characteristic of a singleton class is that there is only one instance of it at any given time (unless it is never used, in which case, there may not be any instances of it depending on how it is implemented).&lt;/p&gt;
&lt;p&gt;Implementing a Singleton is not quite as trivial as it sounds. The intuitive approach is to make the constructor private and provide a public static accessor to it, as shown in &lt;b&gt;Figure 2&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 2 Implementing a Singleton &lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class MySingleton{    private static MySingleton _instance;     private MySingleton()    {    }     public static MySingleton Instance    {        get        {            if (_instance == null)                _instance = new MySingleton();            return _instance;        }      }     ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;This works fine in single-threaded environments, but not in multi-threaded ones. Two threads could enter the Instance property before the instance variable is instantiated, resulting in two instances of the class. There are a few ways around this,  but the easiest solution in .NET takes advantage of the CLR and its guarantees around initialization of static variables, as shown in &lt;b&gt;Figure 3&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 3 Dealing With Two Instances of the Class&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class MySingleton{    private static readonly MySingleton _instance = new MySingleton();     private MySingleton()    {    }     public static MySingleton Instance    {        get        {            return _instance;        }      }     ...}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The fact that the instance variable is marked static and readonly ensures only one instance can be created, even in multi-threaded environments.  Another side effect is that an instance of MySingleton is always going to be created for the _instance variable, regardless of if it’s needed or not.  This is, however, rarely an issue in real world code.&lt;/p&gt;
&lt;h2&gt;Some Background&lt;/h2&gt;
&lt;p&gt;A common implementation for singletons is to use double-checked locking, like so:&lt;/p&gt;
&lt;pre&gt;if (_instance == null) {&lt;/pre&gt;
&lt;pre&gt;    lock (_initializationLock) {&lt;/pre&gt;
&lt;pre&gt;        if (_instance == null) {&lt;/pre&gt;
&lt;pre&gt;            _instance = new MySingleton();&lt;/pre&gt;
&lt;pre&gt;        }                    &lt;/pre&gt;
&lt;pre&gt;    }                &lt;/pre&gt;
&lt;pre&gt;}&lt;/pre&gt;
&lt;pre&gt;return _instance;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;On the surface, double-checked locking appears to offer the best of all worlds. Singletons are instantiated lazily, are never instantiated if never used, and do not take an expensive lock after the singleton is initialized. Unfortunately, double-checked locking is subtlely broken in the vast majority of cases. You can read more about the problems in &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"&gt;&lt;i&gt;The “Double-Checked Locking is Broken” Declaration&lt;/i&gt;&lt;/a&gt; by David Bacon, et al. Double-checked locking can be fixed on the CLR (and JDK5+) by declaring the _instance variable with the volatile keyword. See &lt;a href="http://msdn.microsoft.com/en-us/library/ms998558.aspx"&gt;&lt;i&gt;Implementing Singleton in C#&lt;/i&gt;&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms954629.aspx"&gt;&lt;i&gt;Exploring the Singleton Design Pattern&lt;/i&gt;&lt;/a&gt; in the MSDN Library&lt;i&gt; &lt;/i&gt;for more information.&lt;/p&gt;
&lt;p&gt;That’s about as detailed as we’re going to get on implementing singletons, because there are a number of good resources already available. Plus, the focus of this article is to move away from them, not add more.&lt;/p&gt;
&lt;p&gt;With that background behind us, the “singleton” classes in ScrewTurn aren’t actually singletons. &lt;b&gt;Figure 4&lt;/b&gt; looks at the AuthChecker class first.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Figure 4 AuthChecker Class&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;public class AuthChecker {     private static AuthChecker instance;    public static AuthChecker Instance     {        get { return instance; }        set { instance = value; }    }     private ISettingsStorageProviderV30 settingsProvider;     public AuthChecker(ISettingsStorageProviderV30 settingsProvider)     {        if(settingsProvider == null) throw new             ArgumentNullException("settingsProvider");         this.settingsProvider = settingsProvider;    }     public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)     {       }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser,         string[] groups)     {       }     public bool CheckActionForPage(PageInfo page, string action,     {       }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider,         string directory, string action,         string currentUser, string[] groups)     {       }}&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The most obvious way you can tell this isn’t a singleton is that it has a public constructor. So the client code can create as many of these as it likes. Furthermore, the class doesn’t actually instantiate the instance variable itself. That is done elsewhere in the code, in StartupTools.cs, using the public constructor.&lt;/p&gt;
&lt;p&gt;That said, it is still used as a singleton within the context of the application. Yes, the code could create more than one instance and re-assign the existing instance and basically treat it like any other class. But in the application’s current state, it doesn’t. This half-way status between singleton and non-singleton would be a bone of contention for us at a code review, so let’s see what we can do to fix it. But first, like any refactoring, we need to justify it.&lt;/p&gt;
&lt;h2&gt;Other videos from this article&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/"&gt;Demoing Different Singleton Implementations&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Testability/"&gt;How Singletons Affect Testability&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-AuthChecker-Class/"&gt;Looking At AuthChecker&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Refactoring/"&gt;Walkthrough Of The Entire Refactoring&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read the full article at &lt;a href="http://msdn.microsoft.com/magazine/ee343987.aspx"&gt;http://msdn.microsoft.com/magazine/ee343987.aspx&lt;/a&gt; &lt;/p&gt;&lt;img src="http://channel9.msdn.com/482728/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/</comments><itunes:summary>Extreme ASP.NET Makeover: Death of a Singleton-Overview
Let’s review one of the changes we made to the code in part 6. In that discussion, we refactored the authorization checking into a separate class, AuthorizationServices. To do that, we moved a lot of code from the Page_Load method of our Default.aspx page into it. Figure 1 shows an excerpt from the RetrieveCurrentStatusFor method.
Figure 1 Excerpt from the RetrieveCurrentStatusFor Method
return new CurrentCapabilitiesStatus{    CanView = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ReadPage,        currentUsername, currentGroups),    CanDownloadAttachments = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.DownloadAttachments,        currentUsername, currentGroups),    CanSetPerms = AuthChecker.Instance.CheckActionForGlobals(        Actions.ForGlobals.ManagePermissions,        currentUsername, currentGroups),    CanAdmin = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ManagePage,        currentUsername, currentGroups),    CanViewDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ReadDiscussion,        currentUsername, currentGroups),    CanPostDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.PostDiscussion,        currentUsername, currentGroups),    CanManageDiscussion = AuthChecker.Instance.CheckActionForPage(        currentPage, Actions.ForPages.ManageDiscussion,        currentUsername, currentGroups),    CanEdit = canEdit,    CanEditWithApproval = canEditWithApproval};

Notice all the calls to AuthChecker.Instance. This is an example of the Singleton Design Pattern at work. We’ll define it now to get everyone on the same page.
There Can Be Only One
The defining characteristic of a singleton class is that there is only one instance of it at any given time (unless it is never used, in which case, there may not be any instances of it depending on how it is implemented).
Implementing a Singleton is not quite as trivial as it sounds. The intuitive approach is to make the constructor private and provide a public static accessor to it, as shown in Figure 2.
Figure 2 Implementing a Singleton 
public class MySingleton{    private static MySingleton _instance;     private MySingleton()    {    }     public static MySingleton Instance    {        get        {            if (_instance == null)                _instance = new MySingleton();            return _instance;        }      }     ...}

This works fine in single-threaded environments, but not in multi-threaded ones. Two threads could enter the Instance property before the instance variable is instantiated, resulting in two instances of the class. There are a few ways around this,  but the easiest solution in .NET takes advantage of the CLR and its guarantees around initialization of static variables, as shown in Figure 3.
Figure 3 Dealing With Two Instances of the Class
public class MySingleton{    private static readonly MySingleton _instance = new MySingleton();     private MySingleton()    {    }     public static MySingleton Instance    {        get        {            return _instance;        }      }     ...}

The fact that the instance variable is marked static and readonly ensures only one instance can be created, even in multi-threaded environments.  Another side effect is that an instance of MySingleton is always going to be created for the _instance variable, regardless of if it’s needed or not.  This is, however, rarely an issue in real world code.
Some Background
A common implementation for singletons is to use double-checked locking, like so:
if (_instance == null) {
    lock (_initializationLock) {
        if (_instance == null) {
            _instance = new MySingleton();
        }                    
    }                
}
return _instance;
 
On the surface, double-checked locking appears to offer the best of all worlds. Singletons are instantiated lazily, are never instantiated if never used, and do not take an expensive lock after the singleton is initialized. Unfortunately, double-checked locking is subtlely broken in the vast majority of cases. You can read more about the problems in The “Double-Checked Locking is Broken” Declaration by David Bacon, et al. Double-checked locking can be fixed on the CLR (and JDK5+) by declaring the _instance variable with the volatile keyword. See Implementing Singleton in C# and Exploring the Singleton Design Pattern in the MSDN Library for more information.
That’s about as detailed as we’re going to get on implementing singletons, because there are a number of good resources already available. Plus, the focus of this article is to move away from them, not add more.
With that background behind us, the “singleton” classes in ScrewTurn aren’t actually singletons. Figure 4 looks at the AuthChecker class first.
Figure 4 AuthChecker Class
public class AuthChecker {     private static AuthChecker instance;    public static AuthChecker Instance     {        get { return instance; }        set { instance = value; }    }     private ISettingsStorageProviderV30 settingsProvider;     public AuthChecker(ISettingsStorageProviderV30 settingsProvider)     {        if(settingsProvider == null) throw new             ArgumentNullException("settingsProvider");         this.settingsProvider = settingsProvider;    }     public bool CheckActionForGlobals(string action,         string currentUser, string[] groups)     {       }     public bool CheckActionForNamespace(NamespaceInfo nspace,         string action, string currentUser,         string[] groups)     {       }     public bool CheckActionForPage(PageInfo page, string action,     {       }     public bool CheckActionForDirectory(        IFilesStorageProviderV30 provider,         string directory, string action,         string currentUser, string[] groups)     {       }}

The most obvious way you can tell this isn’t a singleton is that it has a public constructor. So the client code can create as many of these as it likes. Furthermore, the class doesn’t actually instantiate the instance variable itself. That is done elsewhere in the code, in StartupTools.cs, using the public constructor.
That said, it is still used as a singleton within the context of the application. Yes, the code could create more than one instance and re-assign the existing instance and basically treat it like any other class. But in the application’s current state, it doesn’t. This half-way status between singleton and non-singleton would be a bone of contention for us at a code review, so let’s see what we can do to fix it. But first, like any refactoring, we need to justify it.
Other videos from this article

    Demoing Different Singleton Implementations 
    How Singletons Affect Testability 
    Looking At AuthChecker 
    Walkthrough Of The Entire Refactoring 

Read the full article at http://msdn.microsoft.com/magazine/ee343987.aspx </itunes:summary><link>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/</link><pubDate>Tue, 04 Aug 2009 23:56:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.mp4</guid><evnet:views>5536</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/482728/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Let’s review one of the changes we made to the code in part 6. In that discussion, we refactored the authorization checking into a separate class, AuthorizationServices. To do that, we moved a lot of code from the Page_Load method of our Default.aspx page into it.</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.mp4" expression="full" duration="511" fileSize="13314207" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.mp3" expression="full" duration="511" fileSize="4089664" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.mp4" expression="full" duration="511" fileSize="13314207" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.wma" expression="full" duration="511" fileSize="4138475" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_2MB_ch9.wmv" expression="full" duration="511" fileSize="9579476" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_2MB_ch9.wmv" expression="full" duration="511" fileSize="9579476" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_Zune_ch9.wmv" expression="full" duration="511" fileSize="12508647" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/7/2/8/4/DemoingDifferentSingletonImpls_ch9.mp4" length="13314207" type="video/mp4" /><dc:creator>Howard Dierking</dc:creator><itunes:author>Howard Dierking</itunes:author><slash:comments>0</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/howarddierking/Extreme-ASPNET-Makeover-Singleton-Overview/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/482728/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Brownfield Development</category><category>MSDN Magazine</category><category>Patterns</category><category>Singleton</category></item><item><title>Hanselminutes on 9 - ASP.NET MVC 2 Preview 1 with Phil Haack and Virtual Scott</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_small_ch9.png" border="0" /&gt;Scott's in Redmond (or IS he?) and talking to &lt;a href="http://haacked.com/archive/2009/07/30/asp.net-mvc-released.aspx"&gt;Phil Haack&lt;/a&gt; about the release of &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC 2 Preview 1&lt;/a&gt;. Phil give us a tour of some of the new features in this high-tech and inappropriate use of technology. A video of a Phil's screen? Hasn't Scott or Phil heard of a screencast? Still, enjoy. :) &lt;br /&gt;
You can &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=D34F9EAA-FCBE-4E20-B2FD-A9A03DE7D6DD&amp;amp;displaylang=en"&gt;download ASP.NET MVC 2 Preview 1&lt;/a&gt; if you like, too.&lt;img src="http://channel9.msdn.com/481693/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/</comments><itunes:summary>Scott's in Redmond (or IS he?) and talking to Phil Haack about the release of ASP.NET MVC 2 Preview 1. Phil give us a tour of some of the new features in this high-tech and inappropriate use of technology. A video of a Phil's screen? Hasn't Scott or Phil heard of a screencast? Still, enjoy.  
You can download ASP.NET MVC 2 Preview 1 if you like, too.</itunes:summary><link>http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/</link><pubDate>Fri, 31 Jul 2009 06:15:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.mp4</guid><evnet:views>62418</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/481693/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Scott's in Redmond (or IS he?) and talking to Phil Haack about the release of ASP.NET MVC 2 Preview 1. Phil give us a tour of some of the new features in this high-tech and inappropriate use of technology. A video of a Phil's screen? Hasn't Scott or Phil heard of a screencast? Still, enjoy. &lt;img src='/emoticons/C9/emotion-1.gif' alt='Smiley' /&gt; You can download ASP.NET MVC 2 Preview 1 if you like, too.</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.mp4" expression="full" duration="904" fileSize="113798382" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.mp3" expression="full" duration="904" fileSize="7237162" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.mp4" expression="full" duration="904" fileSize="113798382" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.wma" expression="full" duration="904" fileSize="7328729" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_2MB_ch9.wmv" expression="full" duration="904" fileSize="130890913" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_2MB_ch9.wmv" expression="full" duration="904" fileSize="130890913" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_Zune_ch9.wmv" expression="full" duration="904" fileSize="128450169" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/3/9/6/1/8/4/HanselminutesOn9ASPNETMVC2p1New_ch9.mp4" length="113798382" type="video/mp4" /><dc:creator>Glucose</dc:creator><itunes:author>Glucose</itunes:author><slash:comments>32</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-MVC-2-Preview-1-with-Phil-Haack-and-Virtual-Scott/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/481693/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>ASP.NET 4</category><category>ASP.NET MVC</category><category>HanselminutesOn9</category></item><item><title>Jan Welker über dotnet-kicks.de</title><description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_small_ch9.png" border="0" /&gt;Auf dem &lt;a href="http://ulm.netopenspace.de/2009/"&gt;.NET Open Space Süd&lt;/a&gt; hatte ich die Gelegenheit mit &lt;a href="http://blog.jan-welker.de/"&gt;Jan Welker&lt;/a&gt; über das Projekt &lt;a href="http://dotnet-kicks.de/"&gt;dotnet-kicks.de&lt;/a&gt; zu sprechen. Jan erzählt was letztendlich mit dieser Seite gemacht werden kann und wie es dazu kam das er zusammen mit &lt;a href="http://gordon-breuer.de/"&gt;Gordon&lt;/a&gt; und &lt;a href="http://blog.klaus-b.net/default.aspx"&gt;Klaus&lt;/a&gt; diese Seite aufgebaut hat.&lt;br /&gt;
&lt;br /&gt;
Viel Spaß beim reinschauen,&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/dparys"&gt;Dariusz&lt;/a&gt;&lt;img src="http://channel9.msdn.com/481095/WebViewBug.aspx?EVT=0" height="1" width="1" alt="" /&gt;</description><comments>http://channel9.msdn.com/posts/Dariusz/Jan-Welker-ber-dotnet-kicksde/</comments><itunes:summary>Auf dem .NET Open Space Süd hatte ich die Gelegenheit mit Jan Welker über das Projekt dotnet-kicks.de zu sprechen. Jan erzählt was letztendlich mit dieser Seite gemacht werden kann und wie es dazu kam das er zusammen mit Gordon und Klaus diese Seite aufgebaut hat.

Viel Spaß beim reinschauen,
Dariusz</itunes:summary><link>http://channel9.msdn.com/posts/Dariusz/Jan-Welker-ber-dotnet-kicksde/</link><pubDate>Mon, 27 Jul 2009 15:43:00 GMT</pubDate><guid isPermaLink="false">http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.mp4</guid><evnet:views>9606</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/481095/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Auf dem .NET Open Space Süd hatte ich die Gelegenheit mit Jan Welker über das Projekt dotnet-kicks.de zu sprechen. Jan erzählt was letztendlich mit dieser Seite gemacht werden kann und wie es dazu kam das er zusammen mit Gordon und Klaus diese Seite aufgebaut hat.

Viel Spaß beim reinschauen,
Dariusz</evnet:previewtext><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_large_ch9.png" height="240" width="320" /><media:thumbnail url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_small_ch9.png" height="64" width="85" /><media:group><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.mp4" expression="full" duration="333" fileSize="39949583" type="video/mp4" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.mp3" expression="full" duration="333" fileSize="2665854" type="audio/mp3" medium="audio" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.mp4" expression="full" duration="333" fileSize="39949583" type="video/mp4" medium="video" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.wma" expression="full" duration="333" fileSize="2702569" type="audio/x-ms-wma" medium="audio" /><media:content isDefault="true" url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.wmv" expression="full" duration="333" fileSize="73610247" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_2MB_ch9.wmv" expression="full" duration="333" fileSize="219663525" type="video/x-ms-wmv" medium="video" /><media:content url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_Zune_ch9.wmv" expression="full" duration="333" fileSize="40314175" type="video/x-ms-wmv" medium="video" /></media:group><enclosure url="http://mschnlnine.vo.llnwd.net/d1/ch9/5/9/0/1/8/4/dpdnkjanwelker_ch9.mp4" length="39949583" type="video/mp4" /><dc:creator>Dariusz Parys</dc:creator><itunes:author>Dariusz Parys</itunes:author><slash:comments>3</slash:comments><wfw:commentRss>http://channel9.msdn.com/posts/Dariusz/Jan-Welker-ber-dotnet-kicksde/RSS/</wfw:commentRss><trackback:ping>http://channel9.msdn.com/481095/Trackback.aspx</trackback:ping><category>ASP.NET</category><category>Community</category><category>de-de</category><category>Programming</category></item></channel></rss>