<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://davesbox.com/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>Dave's Box : Compatibility, API Design</title><link>http://davesbox.com/archive/tags/Compatibility/API+Design/default.aspx</link><description>Tags: Compatibility, API Design</description><dc:language>en</dc:language><generator>CommunityServer 2008 (Build: 30417.1769)</generator><item><title>Moving a type from one assembly to another using TypeForwardedToAttribute</title><link>http://davesbox.com/archive/2008/12/19/moving-a-type-from-one-assembly-to-another-using-TypeForwardedToAttribute.aspx</link><pubDate>Fri, 19 Dec 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">2122c344-89bc-4cd7-b145-b0515ba3439f:1077</guid><dc:creator>David Kean</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://davesbox.com/rsscomments.aspx?PostID=1077</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://davesbox.com/commentapi.aspx?PostID=1077</wfw:comment><comments>http://davesbox.com/archive/2008/12/19/moving-a-type-from-one-assembly-to-another-using-TypeForwardedToAttribute.aspx#comments</comments><description>&lt;p&gt;One of the problems that we&amp;rsquo;re facing today in the Framework, mainly stemming from the &lt;a href="http://www.danielmoth.com/Blog/2007/06/net-framework-35.html"&gt;red bits/green bits&lt;/a&gt; design of .NET 3.5, is that certain &amp;lsquo;core&amp;rsquo; types are located in the wrong assemblies.&lt;/p&gt;
&lt;p&gt;For example, the extremely useful &lt;a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection&amp;lt;T&amp;gt;&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms668620.aspx"&gt;ReadOnlyObservableCollection&amp;lt;T&amp;gt;&lt;/a&gt; types both live in WindowsBase.dll, which is a part of the Windows Presentation Foundation. For low-level assemblies (such as my team&amp;rsquo;s very own &lt;a href="http://www.codeplex.com/MEF"&gt;System.ComponentModel.Composition.dll&lt;/a&gt;), this means that to use types such as these, they need to take a reference to assemblies either at a higher level to themselves, or to technologies outside of their own. This is in turn leads to scary dependencies, such as the server assembly System.Web.dll&amp;rsquo;s current direct dependency on the client assembly System.Windows.Forms.dll in .NET 2.0.&lt;/p&gt;
&lt;p&gt;Going forward for .NET 4.0, the Framework Architecture team will be leading an effort (being pushed by my colleague &lt;a href="http://blogs.msdn.com/mirceat/"&gt;Mitch Trofin&lt;/a&gt;) to move these and other core types to lower-level assemblies such as mscorlib.dll and System.dll.&lt;/p&gt;
&lt;p&gt;Now, as &lt;a href="http://davesbox.com/archive/2008/12/09/quot-i-can-t-believe-microsoft-didn-t-make-enter-api-name-here-public-quot.aspx"&gt;I&amp;rsquo;ve mentioned previously&lt;/a&gt;, Microsoft takes compatibility very seriously, so you might be thinking &amp;lsquo;how can they move these types without runtime breaking changes&amp;rsquo;?&lt;/p&gt;
&lt;p&gt;Luckily, there&amp;rsquo;s already a solution for this; &lt;em&gt;type forwarding&lt;/em&gt;. Introduced in .NET 2.0, type forwarding allows assembly writers to move types into other assemblies without needing existing consumers to recompile their applications. This done via the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.typeforwardedtoattribute.aspx"&gt;TypeFowardedToAttribute&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To move a type, do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move the type from the original assembly to the assembly that will become the type&amp;rsquo;s new home.&lt;/li&gt;
&lt;li&gt;In the original assembly, add a reference to the new assembly if it does not already have one.&lt;/li&gt;
&lt;li&gt;Apply the following assembly-level attribute to the original assembly, replacing MyType with the type you moved in step 1:
&lt;pre class="code"&gt;[&lt;span style="color:blue;"&gt;assembly&lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;TypeForwardedToAttribute&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MyType&lt;/span&gt;))]&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Compile both assemblies and that&amp;rsquo;s it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A couple of things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The type must have the same name and namespace in the target assembly. &lt;/li&gt;
&lt;li&gt;This is considered a source breaking change; that is, users recompiling their application against the new versions of the assemblies, will be required to add a reference to the assembly that now contains the type. &lt;/li&gt;
&lt;li&gt;While fully supported by C# and C++/CLI, Visual Basic does not support moving types using the &lt;strong&gt;TypeForwardedToAttribute&lt;/strong&gt;. It does, however, support consuming assemblies written by other languages that have had their types moved. &lt;/li&gt;
&lt;li&gt;Starting in .NET 4.0, a new attribute called &lt;strong&gt;TypeForwardedFromAttribute&lt;/strong&gt; should be applied to types that have been forwarded indicating which assembly they came from. This allows runtime serialization to serialize these types correctly when interoping with previous versions of these assemblies. &lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://davesbox.com/aggbug.aspx?PostID=1077" width="1" height="1"&gt;</description><category domain="http://davesbox.com/archive/tags/BCL/default.aspx">BCL</category><category domain="http://davesbox.com/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://davesbox.com/archive/tags/API+Design/default.aspx">API Design</category><category domain="http://davesbox.com/archive/tags/Compatibility/default.aspx">Compatibility</category></item><item><title>"I can't believe Microsoft didn't make [Enter API Name Here] public"</title><link>http://davesbox.com/archive/2008/12/09/quot-i-can-t-believe-microsoft-didn-t-make-enter-api-name-here-public-quot.aspx</link><pubDate>Tue, 09 Dec 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">2122c344-89bc-4cd7-b145-b0515ba3439f:1027</guid><dc:creator>David Kean</dc:creator><slash:comments>29</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://davesbox.com/rsscomments.aspx?PostID=1027</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://davesbox.com/commentapi.aspx?PostID=1027</wfw:comment><comments>http://davesbox.com/archive/2008/12/09/quot-i-can-t-believe-microsoft-didn-t-make-enter-api-name-here-public-quot.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy Miller&lt;/a&gt; takes a dig at the &lt;a href="http://blogs.msdn.com/bclteam/"&gt;BCL team&lt;/a&gt; with his post, &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/12/04/i-love-ayende-and-oss.aspx"&gt;I love Ayende (and OSS)&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;From one of &lt;/em&gt;&lt;em&gt;Ayende&lt;/em&gt;&lt;em&gt;&amp;#39;s many OSS projects.&lt;/em&gt; &lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;This class actually already exists in the System.Core assembly...as an internal class.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;I can only speculate as to why it is internal, but it is obviously much too dangerous
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;for anyone outside of Microsoft to be using... &lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;em&gt;And dear MS BCL team, since so many people are already using Reflector to go get the ExpressionVisitor code, would you just make this public?&amp;nbsp; &amp;#39;K, thx.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This seems like an oversight that this wasn&amp;#39;t public in first place. It would just be a couple minutes of a single developer&amp;#39;s time to change the accessibility from internal to public, right?&lt;/p&gt;
&lt;p&gt;Well, actually, it&amp;#39;s &lt;em&gt;a lot&lt;/em&gt; more complicated than that. There&amp;#39;s very good reasons we don&amp;#39;t make things public and virtual by default; Eric Lippert summarizes it pretty well with his post, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2003/10/28/53298.aspx"&gt;How many Microsoft employees does it take to change a lightbulb?&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;One dev to spend five minutes implementing ChangeLightBulbWindowHandleEx. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One program manager to write the specification. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One localization expert to review the specification for localizability issues. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One usability expert to review the specification for accessibility and usability issues. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;At least one dev, tester and PM to brainstorm security vulnerabilities. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One PM to add the security model to the specification. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One tester to write the test plan. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One test lead to update the test schedule. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One tester to write the test cases and add them to the nightly automation. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Three or four testers to participate in an ad hoc bug bash. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One technical writer to write the documentation. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One technical reviewer to proofread the documentation. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One copy editor to proofread the documentation. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;One documentation manager to integrate the new documentation into the existing body of text, update tables of contents, indexes, etc. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Twenty-five translators to translate the documentation and error messages into all the languages supported by Windows.The managers for the translators live in Ireland (European languages) and Japan (Asian languages), which are both severely time-shifted from Redmond, so dealing with them can be a fairly complex logistical problem. &lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A team of senior managers to coordinate all these people, write the cheques, and justify the costs to their Vice President.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the excellent reasons that Eric lists (and the one that often gets forgotten) is compatibility. Despite what appears to be &lt;a href="http://www.hanselman.com/blog/UpdateOnNETFramework35SP1AndWindowsUpdate.aspx"&gt;evidence to the contrary&lt;/a&gt;, the compatibility bar between versions of the Framework is extremely high. Every single public member and type and its behavior needs be maintained indefinitely. The more APIs that are public and/or virtual, the more baggage that needs to be brought forward into future Framework versions so as to not break compatibility.&lt;/p&gt;
&lt;p&gt;Developing good APIs is extremely difficult, especially the first time around. When we get things wrong (and we do get things wrong), trying to maintain backwards compatibility often stifles innovation as we try to correct these scenarios. Unfortunately, unlike others, we don&amp;#39;t have the luxury to make &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/08/20/smartinstance-in-structuremap-2-5.aspx"&gt;only 95% of our new versions backwards compatible&lt;/a&gt; with our previous versions.&lt;/p&gt;
&lt;p&gt;It is for these very reasons, we try to make our extension points deliberate and designed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://davesbox.com/aggbug.aspx?PostID=1027" width="1" height="1"&gt;</description><category domain="http://davesbox.com/archive/tags/BCL/default.aspx">BCL</category><category domain="http://davesbox.com/archive/tags/API+Design/default.aspx">API Design</category><category domain="http://davesbox.com/archive/tags/Compatibility/default.aspx">Compatibility</category></item></channel></rss>