<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.oosterkamp.nl/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Thomas Huijer : .NET Framework, Visual Studio</title><link>http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/.NET+Framework/Visual+Studio/default.aspx</link><description>Tags: .NET Framework, Visual Studio</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>Applications built for the 3.0 Framework with VS2005 might not compile in VS2005</title><link>http://blogs.oosterkamp.nl/blogs/thomas/archive/2008/12/12/applications-built-for-the-3-0-framework-with-vs2005-might-not-compile-in-vs2005.aspx</link><pubDate>Fri, 12 Dec 2008 21:26:01 GMT</pubDate><guid isPermaLink="false">6da500ce-fa22-46ef-b417-4864733669f6:183</guid><dc:creator>Thomas</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.oosterkamp.nl/blogs/thomas/rsscomments.aspx?PostID=183</wfw:commentRss><comments>http://blogs.oosterkamp.nl/blogs/thomas/archive/2008/12/12/applications-built-for-the-3-0-framework-with-vs2005-might-not-compile-in-vs2005.aspx#comments</comments><description>&lt;p&gt;Recently we&amp;#39;ve encountered some problems when compiling a .NET 3.0 application in Visual Studio 2005. The weird thing was that we could compile and run the application on our local machines, but the build computer we used refused to compile the application due to the simple fact that the code wouldn&amp;#39;t compile. It called methods that existed, but an overload was used that didn&amp;#39;t exist. &lt;p&gt;The local computer and the build computer had a 3.0 Framework or higher installed. Both had the same Visual Studio 2005 installed. Both had the same service packs installed. We just couldn&amp;#39;t figure out what was different on those machines. &lt;p&gt;It turned out that the local computer had only a 3.5 Framework installed. All references in the project were to the 3.0 Framework, so everything compiled just fine. But Intellisense reads the metadata from the actual assebly being referenced, which was on the build computer the 3.5 assemblies. So on the build computer we had these overloads of Dispatcher.Invoke, all coming from the 3.0 assemblies: &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591593(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, Delegate) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591596(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, Delegate, Object) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591595(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, TimeSpan, Delegate) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591594(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, Delegate, Object, Object[]) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591597(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, TimeSpan, Delegate, Object) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591598(VS.85).aspx"&gt;Dispatcher.Invoke (DispatcherPriority, TimeSpan, Delegate, Object, Object[]) &lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;But on the local machine with only the 3.5 Framework we had these overloads:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591593.aspx"&gt;Invoke(DispatcherPriority, Delegate)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc647509.aspx"&gt;Invoke(Delegate, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591596.aspx"&gt;Invoke(DispatcherPriority, Delegate, Object)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591595.aspx"&gt;Invoke(DispatcherPriority, TimeSpan, Delegate)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc647494.aspx"&gt;Invoke(Delegate, TimeSpan, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc647499.aspx"&gt;Invoke(Delegate, DispatcherPriority, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591594.aspx"&gt;Invoke(DispatcherPriority, Delegate, Object, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591597.aspx"&gt;Invoke(DispatcherPriority, TimeSpan, Delegate, Object)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc647498.aspx"&gt;Invoke(Delegate, TimeSpan, DispatcherPriority, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms591598.aspx"&gt;Invoke(DispatcherPriority, TimeSpan, Delegate, Object, array&amp;lt;Object&amp;gt;[]()[])&lt;/a&gt;&lt;br /&gt; &lt;p&gt;So if we used any overload from the latter list that is not in the first list, it&amp;#39;d not compile on the build computer. So, programmer beware: an application built in VS2005 might not compile in VS2005.  &lt;img src="http://blogs.oosterkamp.nl/aggbug.aspx?PostID=183" width="1" height="1"&gt;</description><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/.NET+Framework/default.aspx">.NET Framework</category></item><item><title>Automated testing en databases</title><link>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/12/14/unit-testing-en-databases.aspx</link><pubDate>Fri, 14 Dec 2007 21:29:44 GMT</pubDate><guid isPermaLink="false">6da500ce-fa22-46ef-b417-4864733669f6:61</guid><dc:creator>Thomas</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.oosterkamp.nl/blogs/thomas/rsscomments.aspx?PostID=61</wfw:commentRss><comments>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/12/14/unit-testing-en-databases.aspx#comments</comments><description>&lt;p&gt;Eerlijksheidshalve gebied mij te zeggen dat ik dit artikel eerst &amp;quot;Unit testing en databases&amp;quot; wilde noemen. Maar &lt;a href="http://www.dotned.nl/blogs/dennis_blog/default.aspx" target="_blank"&gt;Dennis Vroegop&lt;/a&gt; corrigeerde me gelijk toen ik het met hem hier over had. Zodra je een database bij je testen gebruikt, zijn het automatisch integration tests. Ik moet Dennis helemaal gelijk geven. Er worden tegenwoordig veel te veel dingen unit-tests genoemd...&lt;/p&gt; &lt;p&gt;Automated testing en databases is een verhaal apart. Er zijn verschillende manieren om het te tackelen, maar in feite heb je twee echte keuzes: je gebruikt &lt;a class="" href="http://en.wikipedia.org/wiki/Mock_object"&gt;mock-objects&lt;/a&gt; of je gebruikt een echte database. Ik gebruik zelf het liefste een echte database. Mijn argument daarvoor is dat je je triggers, stored procedures, etc., etc. ook goed wilt kunnen testen. Dat is met mock-objects gewoon niet te doen.&lt;/p&gt; &lt;p&gt;Een echte database gebruiken heeft wel een nadeel. Je moet er voor zorgen dat je testdata constant is. Als je testen runnen, moet het voor elke testrun wel altijd op dezelfde data zijn. En hoe ga je er voor zorgen dat als je bepaalde data nodig hebt voor een test, dat die data ook altijd bij het runnen van je test in je database zit? Als je een lege tabel nodig hebt voor de ene test en een goed gevulde (zelfde) tabel voor een andere test. Hoe ga je daar mee om op een overzichtelijke manier? Hoe weet je welke data in welke test wordt gebruikt?&lt;/p&gt; &lt;p&gt;De meeste unit-test frameworks hebben daar niet echt ondersteuning voor. Dus voor een hobby projectje voor een &lt;a class="" href="http://www.f1.com/"&gt;Formule1&lt;/a&gt; manager spel, ben ik hier eens mee aan de slag gegaan. Nu gebruik ik zelf eigenlijk altijd de &lt;a class="" href="http://msdn2.microsoft.com/en-us/library/ms243147(VS.80).aspx"&gt;geintegreerde unit-testing van Visual Studio 2005/2008&lt;/a&gt;. Ik weet dat er andere, misschien wel &lt;a class="" href="http://www.mbunit.com/"&gt;betere&lt;/a&gt; zijn, maar ik vind de integratie in VS gewoon lekker. Maar hoe breid ik dit framework nou zo uit, dat ik bovenstaande problemen makkelijk kan oplossen?&lt;/p&gt; &lt;p&gt;De eerste stap was een base-class maken voor mijn testen. Hierin kan ik dan functionaliteit toevoegen die ik nodig heb voor het runnen van mijn database testen.&lt;/p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt;&lt;/div&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;TestClass&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;UnitTestBase&lt;/span&gt;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TestContext&lt;/span&gt; TestContext { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;TestInitialize&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestInitializeInvoker()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestInitialize();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestInitialize()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;TestCleanup&lt;/span&gt;()]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestCleanupInvoker()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestCleanup();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestCleanup()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Volgende stap was om te zorgen dat elke test een connectie naar de database heeft en een transactie start. Door &lt;strong&gt;na&lt;/strong&gt; elke test een Rollback te doen, blijft de database constant qua data. Dus ik maakte een class die tegen de testdatabase kon praten: connecties creeren en openen en scriptjes uitvoeren. De scriptjes zou ik dan opnemen als resource in de test-assembly. Ook koos ik er voor om een DbProviderFactory te gebruiken, zodat ik niet vast hing aan 1 bepaald type database.&lt;/p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TestDatabase&lt;/span&gt;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IDbConnection&lt;/span&gt; GetConnection()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;DbConnection&lt;/span&gt; connection = DbProvider.CreateConnection();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.ConnectionString = ConnectionString;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; connection;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IDbConnection&lt;/span&gt; OpenConnection()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;IDbConnection&lt;/span&gt; connection = DbProvider.CreateConnection();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.ConnectionString = ConnectionString;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.Open();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; connection;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; GetSql( &lt;span style="color:blue;"&gt;string&lt;/span&gt; resourceName )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; fullResourceName = ResourceAssembly.GetName().Name + ( &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.IsNullOrEmpty( ScriptsFolder ) ? &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; : &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; + ScriptsFolder + &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; ) + resourceName;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Stream&lt;/span&gt; resourceStream = ResourceAssembly.GetManifestResourceStream( fullResourceName );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( resourceStream == &lt;span style="color:blue;"&gt;null&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FileNotFoundException&lt;/span&gt;( &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.Format( &lt;span style="color:#a31515;"&gt;&amp;quot;Resource {0} not found.&amp;quot;&lt;/span&gt;, resourceName ) );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;TextReader&lt;/span&gt; textReader = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;StreamReader&lt;/span&gt;( resourceStream );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt; sql = textReader.ReadToEnd();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; textReader.Close();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; sql;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteSql( &lt;span style="color:blue;"&gt;string&lt;/span&gt; sql )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteSql( sql, &lt;span style="color:blue;"&gt;null&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteSql( &lt;span style="color:blue;"&gt;string&lt;/span&gt; sql, &lt;span style="color:#2b91af;"&gt;IDbTransaction&lt;/span&gt; transaction )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.IsNullOrEmpty( sql ) )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;string&lt;/span&gt;[] splittedSql = sql.Split( &lt;span style="color:#a31515;"&gt;&amp;#39;;&amp;#39;&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( splittedSql.Length &amp;gt; 1 )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; ( &lt;span style="color:blue;"&gt;string&lt;/span&gt; singleSql &lt;span style="color:blue;"&gt;in&lt;/span&gt; splittedSql )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteSql( singleSql, transaction );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;IDbCommand&lt;/span&gt; command = DbProvider.CreateCommand();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.Connection = transaction == &lt;span style="color:blue;"&gt;null&lt;/span&gt; ? GetConnection() : transaction.Connection;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.CommandText = sql;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; closeConnection = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( command.Connection.State == &lt;span style="color:#2b91af;"&gt;ConnectionState&lt;/span&gt;.Closed )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.Connection.Open();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; closeConnection = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (transaction != &lt;span style="color:blue;"&gt;null&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.Transaction = transaction;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.ExecuteNonQuery();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( closeConnection )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command.Connection.Close();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteScript( &lt;span style="color:blue;"&gt;string&lt;/span&gt; scriptName, &lt;span style="color:#2b91af;"&gt;IDbTransaction&lt;/span&gt; transaction )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteSql( GetSql( scriptName ), transaction );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteScript( &lt;span style="color:blue;"&gt;string&lt;/span&gt; scriptName )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteScript( scriptName, &lt;span style="color:blue;"&gt;null&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteDefaultScript()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteScript( defaultScriptName );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteDefaultScript( &lt;span style="color:#2b91af;"&gt;IDbTransaction&lt;/span&gt; transaction)&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteScript( defaultScriptName, transaction );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Maar wat ik niet wilde, was om mijn base-class te laten bepalen tegen welke database de testen zouden worden gerund. Dus ik had nog een class nodig om dit te bepalen. Ik wilde niet alles in een config file stoppen, maar een aparte class laten bepalen in welke type database we testen. Door middel van &lt;a class="" href="http://en.wikipedia.org/wiki/Inversion_of_control"&gt;Inversion of Control&lt;/a&gt; laat ik dat dan een andere class bepalen.&lt;/p&gt; &lt;p&gt;Om nu een test te laten runnen en automatisch een Rollback te doen na het uitvoeren van een test, maakte ik een Attribute.&lt;/p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;AttributeUsage&lt;/span&gt;( &lt;span style="color:#2b91af;"&gt;AttributeTargets&lt;/span&gt;.Method )]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AutoRollbackAttribute&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Attribute&lt;/span&gt;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Als ik dat attribute boven een test zet, dan zorgt de UnitTestBase er voor dat de Rollback automatisch wordt uitgevoerd.&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestInitialize()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _connection = &lt;span style="color:#2b91af;"&gt;TestDatabase&lt;/span&gt;.OpenConnection();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StartTransaction();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;virtual&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; TestCleanup()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; ( HasAutoRollbackAttribute() )&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Transaction.Rollback();&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; HasAutoRollbackAttribute()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;MethodInfo&lt;/span&gt; testMethod = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.GetType().GetMetho( TestContext.TestName );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;object&lt;/span&gt;[] attributes = testMethod.GetCustomAttributes( &lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; typeof&lt;/span&gt;( &lt;span style="color:#2b91af;"&gt;AutoRollbackAttribute&lt;/span&gt; ), &lt;span style="color:blue;"&gt;false&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; attributes.Length &amp;gt; 0;&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp; } &lt;/p&gt;&lt;/div&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt;Een test zou dat alleen (behalve het TestMethod attribute natuurlijk) dan alleen het AutoRollback attribute moeten hebben, om er voor te zorgen dat de test niets veranderd in de database.&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="font-size:10pt;background:white;color:black;font-family:consolas;"&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;TestMethod&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;AutoRollback&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; SomeTest()&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //test implementation&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin:0px;"&gt; Hiermee ben ik dus al een heel end. Maar ik wil ook toch testdata kunnen initialiseren voor een bepaalde test. Data die je alleen voor die test nodig hebt. Maar daar blog ik een volgende keer over. Dan zal ik ook de sourcecode beschikbaar stellen van dit mini &amp;#39;testframework&amp;#39;.&lt;/p&gt; &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.oosterkamp.nl/aggbug.aspx?PostID=61" width="1" height="1"&gt;</description><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Team+System/default.aspx">Team System</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/.NET+Framework/default.aspx">.NET Framework</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/unit-testing/default.aspx">unit-testing</category></item><item><title>Visual Studio 2008 RTM is beschikbaar...</title><link>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/11/19/visual-studio-team-system-2008-team-suite-rtm-is-beschikbaar.aspx</link><pubDate>Mon, 19 Nov 2007 11:40:31 GMT</pubDate><guid isPermaLink="false">6da500ce-fa22-46ef-b417-4864733669f6:76</guid><dc:creator>Thomas</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.oosterkamp.nl/blogs/thomas/rsscomments.aspx?PostID=76</wfw:commentRss><comments>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/11/19/visual-studio-team-system-2008-team-suite-rtm-is-beschikbaar.aspx#comments</comments><description>&lt;p&gt;Op de MSDN Subscriber site is de Visual Studio Team System 2008 Team Suite RTM beschikbaar! Ze hadden al beloofd dat ie &amp;#39;early next week&amp;#39; beschikbaar zou zijn, en maandag, einde van de ochtend, net na de eerste koppen koffie...Ja, dat kwalificieert wel als &amp;#39;early next week&amp;#39;.&lt;/p&gt;&lt;img src="http://blogs.oosterkamp.nl/aggbug.aspx?PostID=76" width="1" height="1"&gt;</description><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Team+System/default.aspx">Team System</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/.NET+Framework/default.aspx">.NET Framework</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category></item><item><title>Eindelijk source code!</title><link>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/10/03/eindelijk-source-code.aspx</link><pubDate>Wed, 03 Oct 2007 21:00:00 GMT</pubDate><guid isPermaLink="false">6da500ce-fa22-46ef-b417-4864733669f6:56</guid><dc:creator>Thomas</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.oosterkamp.nl/blogs/thomas/rsscomments.aspx?PostID=56</wfw:commentRss><comments>http://blogs.oosterkamp.nl/blogs/thomas/archive/2007/10/03/eindelijk-source-code.aspx#comments</comments><description>&lt;p&gt;Microsoft heeft besloten om de source-code van het .NET Framework te gaan releasen. Goed idee, lijkt me. Ik, met m&amp;#39;n jarenlange Delphi achtergrond, vond het altijd nogal hinderlijk dat je geen source-code had van de classes die je in je applicaties gebruikt. Van de Delphi VCL had je tenminste alle sources. Maar goed, met &lt;a class="" href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt;&amp;nbsp;kwam je natuurlijk al een heel eind, maar locale variabele namen miste je bijvoorbeeld. Met de komst van Visual Studio 2008 en het 3.5 Framework is dat ook weer opgelost. &lt;a class="" href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx"&gt;Hier kun je er meer over lezen&lt;/a&gt; op de blog van Scott Guthrie.&lt;/p&gt;&lt;img src="http://blogs.oosterkamp.nl/aggbug.aspx?PostID=56" width="1" height="1"&gt;</description><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.oosterkamp.nl/blogs/thomas/archive/tags/.NET+Framework/default.aspx">.NET Framework</category></item></channel></rss>