<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0">

<channel>
	<title>GrumpyDev</title>
	
	<link>http://www.grumpydev.com</link>
	<description>The Technical Jibber Jabber of Steven Robbins</description>
	<lastBuildDate>Tue, 09 Mar 2010 13:00:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GrumpyDev" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="grumpydev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><item>
		<title>Automated “Unit” Testing – It’s Not Just for TDD, It’s for Bug Fixing Too!</title>
		<link>http://www.grumpydev.com/2010/03/09/automated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too/</link>
		<comments>http://www.grumpydev.com/2010/03/09/automated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 13:00:32 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[MonoTouch]]></category>
		<category><![CDATA[Rambling]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[TinyIoC]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=293</guid>
		<description><![CDATA[Disclaimer – What I’m discussing here isn’t unit testing (hence the quotes), it’s more functional or integration testing; but as the term “Unit Testing” is often “abused” to mean “anything that uses a (unit) testing framework” so I’ve included it in the title to avoid confusion.
Introduction
I’m currently using TinyIoC in my first forays into MonoTouch [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Disclaimer – What I’m discussing here isn’t unit testing (hence the quotes), it’s more functional or integration testing; but as the term “Unit Testing” is often “abused” to mean “anything that uses a (unit) testing framework” so I’ve included it in the title to avoid confusion.</em></strong></p>
<h2>Introduction</h2>
<p>I’m currently using <a href="http://hg.grumpydev.com/tinyioc" target="_blank">TinyIoC</a> in my first forays into <a href="http://monotouch.net/" target="_blank">MonoTouch</a> development, and my initialisation code was throwing a resolution error on starup:</p>
<pre class="brush: csharp; toolbar: false;">var container = TinyIoCContainer.Current();
var mainView = new MainView();
container.Register&lt;IViewManager&gt;(mainView);
container.Register&lt;IView, MainView&gt;(mainView, "MainView");
container.Register&lt;IView, SplashView&gt;("SplashView").UsingConstructor(() =&gt; new SplashView());
container.Resolve&lt;IView&gt;("MainView");
container.Register&lt;IStateManager, StateManager&gt;();
// Code was blowing up here..
var stateManager = container.Resolve&lt;IStateManager&gt;();
stateManager.Init();</pre>
<p>The Exception that was given was that IStateManager could not be resolved, which was odd given that the StateManager was registered against IStateManager, and everything in its constructor was also registered:</p>
<pre class="brush: csharp; toolbar: false;">public StateManager(IViewManager viewManager, Func&lt;string, IView&gt; viewFactory)</pre>
<h2>To The Debugger.. Right?!</h2>
<p>So at this point your immediate reaction may be to fire up the debugger, trace into the code and start hacking around, debugging and hacking around some more until it works. Sure, that’s an approach, and one I’m sure we’ve all used in the past; but as I was pretty sure the issue was in TinyIoC itself I took a slightly different tack.</p>
<h2>To The Test Runner!</h2>
<p>With the approach above I would have to build and run my app every time I wanted to check if my “fix” had actually worked – and even if it had, how would I know it hadn’t broken something else? The solution is quite simple – recreate the conditions of the bug in a unit test, using stubs/mocks to replace your real classes, and make sure it fails in the same way:</p>
<pre class="brush: csharp; toolbar: false;">[TestMethod]
public void Dependency_Hierarchy_With_Named_Factories_Resolves_All_Correctly()
{
    var container = UtilityMethods.GetContainer();
    var mainView = new MainView();
    container.Register&lt;IViewManager&gt;(mainView);
    container.Register&lt;IView, MainView&gt;(mainView, "MainView");
    container.Register&lt;IView, SplashView&gt;("SplashView").UsingConstructor(() =&gt; new SplashView());
    container.Resolve&lt;IView&gt;("MainView");
    container.Register&lt;IStateManager, StateManager&gt;();
    var stateManager = container.Resolve&lt;IStateManager&gt;();
    stateManager.Init();

    Assert.IsInstanceOfType(mainView.LoadedView, typeof(SplashView));
}</pre>
<p>I&#8217;ve added an Assert to show what behaviour I think it *should* have. It’s a pretty horrible looking test, but it accurately represents what my failing code was doing, and the test fails as I expected it to. Now I can attach the debugger and find out what’s going on, safe in the knowledge I have a fast executing test available to verify my fix, and the rest of my test suite there to ensure I haven’t broken anything else.</p>
<p>After a very brief investigation it turned out that there was a bug in registration when *just* an Interface type was registered with an concrete instance (the IViewManager registration above). The “InstanceFactory” it was using hadn’t set the “AssumeResolves” flag, so TinyIoC was actually trying to find a valid constructor for IViewManager – which obviously wasn’t going to succeed. It&#8217;s a scenario I probably should have factored into my Unit Tests, but hey, nobody is perfect <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Conclusion</h2>
<p>This post is aimed at covering two points:</p>
<ol>
<li>Test aren’t just for TDD. If you find a bug, isolate it with a test and you have a quick and easy way to verify a fix, and verify you haven’t broken anything else.</li>
<li>Code Coverage isn’t everything. Apart from a few “defensive coding” null checks, the core of TinyIoC has pretty much 100% code coverage with its tests, but it didn’t help me with this issue. Although the code path was covered, the exact input (Interface type, concrete instance) wasn’t in my unit tests, so don’t assume 100% code coverage means 0 bugs in the code, there may well be a scenario you missed!</li>
</ol>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Btitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Btitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Btitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Btitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F09%252Fautomated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too%252F%26amp%3Btitle%3DAutomated%2520%2526ldquo%253BUnit%2526rdquo%253B%2520Testing%2520%2526ndash%253B%2520It%2526rsquo%253Bs%2520Not%2520Just%2520for%2520TDD%252C%2520It%2526rsquo%253Bs%2520for%2520Bug%2520Fixing%2520Too%2521';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/csharp' rel='tag' target='_blank'>csharp</a>, <a class='technorati-link' href='http://technorati.com/tag/debugging' rel='tag' target='_blank'>debugging</a>, <a class='technorati-link' href='http://technorati.com/tag/MonoTouch' rel='tag' target='_blank'>MonoTouch</a>, <a class='technorati-link' href='http://technorati.com/tag/testing' rel='tag' target='_blank'>testing</a>, <a class='technorati-link' href='http://technorati.com/tag/TinyIoC' rel='tag' target='_blank'>TinyIoC</a>, <a class='technorati-link' href='http://technorati.com/tag/unit+testing' rel='tag' target='_blank'>unit testing</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2010/03/09/automated-unit-testing-its-not-just-for-tdd-its-for-bug-fixing-too/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing: TinyIoC – An Easy to Use, Hassle Free, Inversion of Control Container</title>
		<link>http://www.grumpydev.com/2010/03/02/announcing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container/</link>
		<comments>http://www.grumpydev.com/2010/03/02/announcing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 06:56:15 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[TinyIoC]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[di]]></category>
		<category><![CDATA[inversion of control]]></category>
		<category><![CDATA[ioc]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=288</guid>
		<description><![CDATA[Introduction
Whenever I start a new “pet” project I usually *want* to use IoC, but I don’t really want the hassle of taking a dependency on a container, or adding another binary to my project. Usually this leaves me using “poor man’s IoC”, whereby I define dependencies in my constructors, but I pass them in manually [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Whenever I start a new “pet” project I usually *want* to use IoC, but I don’t really want the hassle of taking a dependency on a container, or adding another binary to my project. Usually this leaves me using “poor man’s IoC”, whereby I define dependencies in my constructors, but I pass them in manually or construct them using <a href="http://www.csharp411.com/constructor-chaining/" target="_blank">constructor chaining</a>.</p>
<p>I’ve thought for some time that it would be useful to put together a container that fits the bill for that scenario, but also attempts to “lower the barrier of entry” for developers that are new to IoC, and may be scared off by the “big boys”. A couple of weeks ago <a href="http://twitter.com/dotnetwill" target="_blank">@DotNetWill</a> posted his <a href="http://www.humblecoder.co.uk/?p=102" target="_blank">simplified container</a>, and that gave me the kick up the backside I needed to create my own <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Introducing TinyIoC</h2>
<p>Now you might ask “do we really need *another* IoC container?” – and it’s a reasonable question. We already have <a href="http://www.codeplex.com/unity" target="_blank">Unity</a>, <a href="http://ninject.org/" target="_blank">Ninject</a>, <a href="http://structuremap.sourceforge.net/" target="_blank">StructureMap</a>, <a href="http://code.google.com/p/autofac/" target="_blank">AutoFac</a>.. the list goes on. <a href="http://hg.grumpydev.com/tinyioc" target="_blank">TinyIoC</a> makes no attempt to go “head to head” with any of these other containers, instead <a href="http://hg.grumpydev.com/tinyioc" target="_blank">TinyIoC</a> has been designed to fulfil a single key requirement:</p>
<blockquote><p><strong>To lower the &#8220;level of entry&#8221; for using an IoC container; both for small projects, and developers who are new to IoC.</strong></p></blockquote>
<p>To that end, <a href="http://hg.grumpydev.com/tinyioc" target="_blank">TinyIoC</a> attempts to stick the following core principals:</p>
<ul>
<li><strong>Simplified Inclusion.</strong> No assembly to reference, no binary to worry about, just a single cs file you can include in your project and you&#8217;re good to go. It also works on <a href="http://www.mono-project.com/" target="_blank">Mono</a>, and on <a href="http://monotouch.net/" target="_blank">MonoTouch</a> for the iPhone / iPad.</li>
<li><strong>Simplified Setup. </strong>With auto-resolving of concrete types and an &#8220;auto registration&#8221; option for interfaces, setup is a piece of cake. It can be reduced to 0 lines for concrete types, or 1 line if you have any interface dependencies.</li>
<li><strong>Simple, &#8220;Fluent&#8221; API. </strong>Just because it&#8217;s Tiny, doesn&#8217;t mean it has no features. A simple &#8220;fluent&#8221; API gives you access to the more advanced features, like specifying singleton/multi-instance, strong or weak references or forcing a particular constructor.</li>
</ul>
<p>The following snippet gives an example of the simplified setup:</p>
<pre class="brush: csharp; toolbar: false;">// TinyIoC provides a lazyily constructed singleton
// version of itself if you want to use it.
var container = TinyIoCContainer.Current;

// By default we can resolve concrete types without
// registration
var instance = container.Resolve&lt;MyConcreteType&gt;();

// We can automatically register all concrete types
// and interfaces with a single call.
container.AutoRegister();
var implementation = container.Resolve&lt;IMyInterface&gt;();</pre>
<h2>So Where Now?</h2>
<p>If you want to grab the source, read the tests, or take a look at some more complex examples of the API, wander on over to the <a href="http://hg.grumpydev.com/tinyioc" target="_blank">homepage</a> on <a href="http://hg.grumpydev.com/tinyioc" target="_blank">bitbucket</a>. I’m happy to take comments and suggestions – just grab me on <a href="http://twitter.com/grumpydev" target="_blank">Twitter</a> or ping me an email from the <a href="http://www.grumpydev.com/contact/" target="_blank">contact form</a>.</p>
<p>Over the next few weeks I will be posting a series of “beginners” articles on the hows and whys of IoC. I will be using <a href="http://hg.grumpydev.com/tinyioc" target="_blank">TinyIoC</a> specifically, but the majority of concepts and content can equally apply to other containers. I may even do a “File, New” screencast to show how “un-scary” this stuff is, and how it doesn’t really add any extra development effort,</p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%26amp%3Bbodytext%3DIntroduction%250D%250AWhenever%2520I%2520start%2520a%2520new%2520%25E2%2580%259Cpet%25E2%2580%259D%2520project%2520I%2520usually%2520%252Awant%252A%2520to%2520use%2520IoC%252C%2520but%2520I%2520don%25E2%2580%2599t%2520really%2520want%2520the%2520hassle%2520of%2520taking%2520a%2520dependency%2520on%2520a%2520container%252C%2520or%2520adding%2520another%2520binary%2520to%2520my%2520project.%2520Usually%2520this%2520leaves%2520me%2520using%2520%25E2%2580%259Cpoor%2520man%25E2%2580%2599s%2520IoC%25E2%2580';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%26amp%3Bnotes%3DIntroduction%250D%250AWhenever%2520I%2520start%2520a%2520new%2520%25E2%2580%259Cpet%25E2%2580%259D%2520project%2520I%2520usually%2520%252Awant%252A%2520to%2520use%2520IoC%252C%2520but%2520I%2520don%25E2%2580%2599t%2520really%2520want%2520the%2520hassle%2520of%2520taking%2520a%2520dependency%2520on%2520a%2520container%252C%2520or%2520adding%2520another%2520binary%2520to%2520my%2520project.%2520Usually%2520this%2520leaves%2520me%2520using%2520%25E2%2580%259Cpoor%2520man%25E2%2580%2599s%2520IoC%25E2%2580';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container%26amp%3Bbody%3DIntroduction%250D%250AWhenever%2520I%2520start%2520a%2520new%2520%25E2%2580%259Cpet%25E2%2580%259D%2520project%2520I%2520usually%2520%252Awant%252A%2520to%2520use%2520IoC%252C%2520but%2520I%2520don%25E2%2580%2599t%2520really%2520want%2520the%2520hassle%2520of%2520taking%2520a%2520dependency%2520on%2520a%2520container%252C%2520or%2520adding%2520another%2520binary%2520to%2520my%2520project.%2520Usually%2520this%2520leaves%2520me%2520using%2520%25E2%2580%259Cpoor%2520man%25E2%2580%2599s%2520IoC%25E2%2580';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F02%252Fannouncing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container%252F%26amp%3Btitle%3DAnnouncing%253A%2520TinyIoC%2520%2526ndash%253B%2520An%2520Easy%2520to%2520Use%252C%2520Hassle%2520Free%252C%2520Inversion%2520of%2520Control%2520Container';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/csharp' rel='tag' target='_blank'>csharp</a>, <a class='technorati-link' href='http://technorati.com/tag/dependency+injection' rel='tag' target='_blank'>dependency injection</a>, <a class='technorati-link' href='http://technorati.com/tag/di' rel='tag' target='_blank'>di</a>, <a class='technorati-link' href='http://technorati.com/tag/inversion+of+control' rel='tag' target='_blank'>inversion of control</a>, <a class='technorati-link' href='http://technorati.com/tag/ioc' rel='tag' target='_blank'>ioc</a>, <a class='technorati-link' href='http://technorati.com/tag/TinyIoC' rel='tag' target='_blank'>TinyIoC</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2010/03/02/announcing-tinyioc-an-easy-to-use-hassle-free-inversion-of-control-container/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Moving a Repository from SVN to Mercurial With Full History</title>
		<link>http://www.grumpydev.com/2010/03/01/moving-a-repository-from-svn-to-mercurial-with-full-history/</link>
		<comments>http://www.grumpydev.com/2010/03/01/moving-a-repository-from-svn-to-mercurial-with-full-history/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 13:58:30 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=284</guid>
		<description><![CDATA[Disclaimer
Let me start with a disclaimer. I’ve only been using Mercurial for 2 days so my nomenclature may be completely wide of the mark. Hopefully this post will help other hgnewbies with what is probably a common requirement.
Introduction
I keep all of my pet projects in my own Subversion repository but I’ve recently decided to give [...]]]></description>
			<content:encoded><![CDATA[<h2>Disclaimer</h2>
<p>Let me start with a disclaimer. I’ve only been using Mercurial for 2 days so my nomenclature may be completely wide of the mark. Hopefully this post will help other hgnewbies with what is probably a common requirement.</p>
<h2>Introduction</h2>
<p>I keep all of my pet projects in my own Subversion repository but I’ve recently decided to give this distributed version control shenanigans a whirl. I ummed and arred about Git or Mercurial, but in the end I plumped for Mercurial, with a <a href="http://bitbucket.org/" target="_blank">bitbucket</a> account, as it seems to have more ubiquitous support. I’m about to release a project I’ve been working on for the last week or so and thought it would be nice to release it via bitbucket – complete with the version history I’d build up in Subversion.</p>
<p>Turns out, it’s really rather easy!</p>
<h2>I’m Converted!</h2>
<p>I’m assuming at this point you have the commandline version of Mercurial (hg) installed and working. If you don’t then you should probably go and do that first <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  I’ve also assumed you’ve already created a mercurial repository (bitbucket or elsewhere) called “<strong>myproject</strong>”.</p>
<p><em>In my scenario I was converting a single project with no trunk, branch or tag directories. The convert command is capable of handling much more advanced scenarios – take a look at the </em><a href="http://mercurial.selenic.com/wiki/ConvertExtension" target="_blank"><em>documentation</em></a><em> for more infomation.</em></p>
<p>First things first you need to edit your Mercurial settings (.hgrc for *nix, Mercurial.ini in your user dir for Windows) and add the following lines:</p>
<blockquote><p>[extensions]<br />
hgext.convert=</p></blockquote>
<p>This will add the “convert” command extension to our client. Next up we clone our repository and use the new convert command to add the SVN changesets into it:</p>
<blockquote><p>hg clone <a href="https://bitbucket.org/myuser/myproject">https://bitbucket.org/myuser/myproject</a></p>
<p>hg convert <a href="http://mysvn.server.com/svn/myproject/">http://mysvn.server.com/svn/myproject/</a> myproject</p></blockquote>
<p>The convert command will now start counting down the revisions and adding each one to our local hg repository. This may well take some time <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Potential gotcha: it <a href="http://mercurial.selenic.com/bts/issue1783" target="_blank">appears</a> that the convert extension <a href="http://mercurial.selenic.com/bts/issue1783" target="_blank">doesn’t work properly with Subversion repositories over http that require authentication</a>. If you get multiple “http authorization required” messages and prompts for your username/password then you have a problem. The only solution I found was to temporarily disable authentication while I did the conversion <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </strong></p>
<p>Once the conversion had finished we push our changes back:</p>
<blockquote><p>cd myproject</p>
<p>hg push</p></blockquote>
<p>Now at this point for me the push worked fine but my local repository had no files in it – despite insisting it was up to date. This may be my lack of knowledge on Mercurial, or it might be a bug, but deleting the myproject directory locally and cloning the remote repo again sorted things out.</p>
<h2>Conclusion</h2>
<p>All in all a pretty trivial task, albeit one that takes a while with a large repository. The only big issue is the authentication one I mention above – this may well be a showstopper for you if you can’t control the ACL on your Subversion repository.</p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Bannotation%3DDisclaimer%250D%250ALet%2520me%2520start%2520with%2520a%2520disclaimer.%2520I%25E2%2580%2599ve%2520only%2520been%2520using%2520Mercurial%2520for%25202%2520days%2520so%2520my%2520nomenclature%2520may%2520be%2520completely%2520wide%2520of%2520the%2520mark.%2520Hopefully%2520this%2520post%2520will%2520help%2520other%2520hgnewbies%2520with%2520what%2520is%2520probably%2520a%2520common%2520requirement.%250D%250AIntroduction%250D%250AI%2520';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Bbodytext%3DDisclaimer%250D%250ALet%2520me%2520start%2520with%2520a%2520disclaimer.%2520I%25E2%2580%2599ve%2520only%2520been%2520using%2520Mercurial%2520for%25202%2520days%2520so%2520my%2520nomenclature%2520may%2520be%2520completely%2520wide%2520of%2520the%2520mark.%2520Hopefully%2520this%2520post%2520will%2520help%2520other%2520hgnewbies%2520with%2520what%2520is%2520probably%2520a%2520common%2520requirement.%250D%250AIntroduction%250D%250AI%2520';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Bnotes%3DDisclaimer%250D%250ALet%2520me%2520start%2520with%2520a%2520disclaimer.%2520I%25E2%2580%2599ve%2520only%2520been%2520using%2520Mercurial%2520for%25202%2520days%2520so%2520my%2520nomenclature%2520may%2520be%2520completely%2520wide%2520of%2520the%2520mark.%2520Hopefully%2520this%2520post%2520will%2520help%2520other%2520hgnewbies%2520with%2520what%2520is%2520probably%2520a%2520common%2520requirement.%250D%250AIntroduction%250D%250AI%2520';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History%26amp%3Bbody%3DDisclaimer%250D%250ALet%2520me%2520start%2520with%2520a%2520disclaimer.%2520I%25E2%2580%2599ve%2520only%2520been%2520using%2520Mercurial%2520for%25202%2520days%2520so%2520my%2520nomenclature%2520may%2520be%2520completely%2520wide%2520of%2520the%2520mark.%2520Hopefully%2520this%2520post%2520will%2520help%2520other%2520hgnewbies%2520with%2520what%2520is%2520probably%2520a%2520common%2520requirement.%250D%250AIntroduction%250D%250AI%2520';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F03%252F01%252Fmoving-a-repository-from-svn-to-mercurial-with-full-history%252F%26amp%3Btitle%3DMoving%2520a%2520Repository%2520from%2520SVN%2520to%2520Mercurial%2520With%2520Full%2520History';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/convert' rel='tag' target='_blank'>convert</a>, <a class='technorati-link' href='http://technorati.com/tag/hg' rel='tag' target='_blank'>hg</a>, <a class='technorati-link' href='http://technorati.com/tag/history' rel='tag' target='_blank'>history</a>, <a class='technorati-link' href='http://technorati.com/tag/Mercurial' rel='tag' target='_blank'>Mercurial</a>, <a class='technorati-link' href='http://technorati.com/tag/subversion' rel='tag' target='_blank'>subversion</a>, <a class='technorati-link' href='http://technorati.com/tag/svn' rel='tag' target='_blank'>svn</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2010/03/01/moving-a-repository-from-svn-to-mercurial-with-full-history/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>So What Is This “Thread Safe” Thing Anyway?</title>
		<link>http://www.grumpydev.com/2010/02/26/so-what-is-this-thread-safe-thing-anyway/</link>
		<comments>http://www.grumpydev.com/2010/02/26/so-what-is-this-thread-safe-thing-anyway/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 10:10:18 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[concurrentdictionary]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[locks]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=273</guid>
		<description><![CDATA[Introduction
Following on from my previous post about a “Thread Safe” Dictionary, and the subsequent comment from Rajeesh, made me think that perhaps a general post on “thread safety” was in order.
Stop With the Quotes Already!
The astute amongst you may notice I always try and put the phrase “thread safe” in quotes; and there is a [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Following on from my previous post about a <a href="http://www.grumpydev.com/?p=264" target="_blank">“Thread Safe” Dictionary</a>, and the subsequent comment from Rajeesh, made me think that perhaps a general post on “thread safety” was in order.</p>
<h2>Stop With the Quotes Already!</h2>
<p>The astute amongst you may notice I always try and put the phrase “thread safe” in quotes; and there is a good reason for that! “Thread safe” is a pretty horrible term (although I can&#8217;t think of a better one) that doesn’t really give enough detail for what exactly we mean when we express that a class is “thread safe”. As far as I’m concerned, my “library” classes are thread safe if:</p>
<blockquote><p>“All public static and instance methods and properties on the class are safe to be called concurrently from multiple threads.”</p></blockquote>
<p>What this certainly does <strong>*not*</strong> mean is:</p>
<blockquote><p>“You do not have to consider thread safety or concurrency issues in your own code that uses this class.”</p></blockquote>
<p>So in the instance of our dictionary if you get/set a value and then in subsequent lines of code you <strong>*assume that the value you got or set hasn’t changed*</strong> then you have a concurrency issue in <strong>*your*</strong> code and you will <strong>*need to address it, likely using the same </strong><a href="http://msdn.microsoft.com/en-us/library/ms228964(VS.95).aspx" target="_blank"><strong>synchronisation primitives</strong></a><strong> we used internally in our SafeDictionary class.*</strong></p>
<h2>Some Examples</h2>
<p>As an example we can take similar code to the snippet that Rajeesh posted:</p>
<pre class="brush: csharp; toolbar: false;">// Check the item exists and process
// if it does
if (mySafeDictionary["Testing"] != null)
{
    // Process element
    ProcessElement(mySafeDictionary["Testing"]);
}</pre>
<p>Although each of those calls to the SafeDictionary are themselves threadsafe, we are making an assumption in *our code* that those value won’t change between the “if” statement and our call to ProcessElement. This particular scenario is one reason why we should always try to use TryGetValue, rather than the “if it exists do this with it” approach above. To this end we should probably alter our SafeDictionary to explicitly deny gets:</p>
<pre class="brush: csharp; toolbar: false;">public class SafeDictionary&lt;TKey, TValue&gt;
{
    private readonly object _Padlock = new object();
    private readonly Dictionary&lt;TKey, TValue&gt; _Dictionary = new Dictionary&lt;TKey, TValue&gt;();

    public TValue this[TKey key]
    {
        set
        {
            lock (_Padlock)
            {
                _Dictionary[key] = value;
            }
        }
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        lock (_Padlock)
        {
            return _Dictionary.TryGetValue(key, out value);
        }
    }
}</pre>
<p>If you now try and access a member using the array syntax, rather than through TryGetValue you will get a compile time error like:</p>
<blockquote><p>The property or indexer &#8216;Variabler.this[string]&#8216; cannot be used in this context because it lacks the get accessor.</p></blockquote>
<p>From that simple example you may think that TryGetValue solves all our problems; but unfortunately it still isn’t able to save your from yourself! To reiterate what I said earlier, you need to consider concurrency yourself if you <strong>*assume that the value you got or set hasn’t changed*</strong>. Assuming we expand our SafeDictionary to include all of the options that the normal Dictionary supports, take the following horribly contrived example:</p>
<pre class="brush: csharp; toolbar: false;">public List&lt;String&gt; GetKeysToProcess()
{
    object myObject;
    List&lt;String&gt; keysToProcess = new List&lt;String&gt;();

    // Check to see if the type is valid for
    // processing
    foreach (var currentKey in myDictionary.Keys)
    {
        if (myDictionary.TryGetValue(currentKey, out myObject))
        {
            if (myObject.GetType() == typeof(ProcessorClass))
                keysToProcess.Add(currentKey);
        }
    }

    return keysToProcess;
}</pre>
<p>Now there’s a chance that a key might have been removed between the start of the foreach and us actually using it; but as we use TryGetValue that doesn’t matter – the value just won’t resolve. The key here (pardon the pun) is that we are building and returning a list that <strong>*makes assumptions about the contents of the dictionary*</strong>. Even if in our consuming code we stick to TryGetValue to handle items being deleted, there’s nothing in this example preventing another thread changing any of the items to be a different type – effectively rendering our List of “Keys to process” completely invalid.</p>
<h2>Conclusion</h2>
<p>The examples above are very contrived, and I’d hope nobody would ever write those exact pieces of code; but hopefully it illustrates the point that <strong>*just because you are working with a “Thread safe” object doesn’t mean you can ignore thread safety concerns in your own code*.</strong></p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Bannotation%3DIntroduction%250D%250AFollowing%2520on%2520from%2520my%2520previous%2520post%2520about%2520a%2520%25E2%2580%259CThread%2520Safe%25E2%2580%259D%2520Dictionary%252C%2520and%2520the%2520subsequent%2520comment%2520from%2520Rajeesh%252C%2520made%2520me%2520think%2520that%2520perhaps%2520a%2520general%2520post%2520on%2520%25E2%2580%259Cthread%2520safety%25E2%2580%259D%2520was%2520in%2520order.%250D%250AStop%2520With%2520the%2520Quotes%2520Already%2521%250D%250AThe%2520astute%2520';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Bbodytext%3DIntroduction%250D%250AFollowing%2520on%2520from%2520my%2520previous%2520post%2520about%2520a%2520%25E2%2580%259CThread%2520Safe%25E2%2580%259D%2520Dictionary%252C%2520and%2520the%2520subsequent%2520comment%2520from%2520Rajeesh%252C%2520made%2520me%2520think%2520that%2520perhaps%2520a%2520general%2520post%2520on%2520%25E2%2580%259Cthread%2520safety%25E2%2580%259D%2520was%2520in%2520order.%250D%250AStop%2520With%2520the%2520Quotes%2520Already%2521%250D%250AThe%2520astute%2520';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Bnotes%3DIntroduction%250D%250AFollowing%2520on%2520from%2520my%2520previous%2520post%2520about%2520a%2520%25E2%2580%259CThread%2520Safe%25E2%2580%259D%2520Dictionary%252C%2520and%2520the%2520subsequent%2520comment%2520from%2520Rajeesh%252C%2520made%2520me%2520think%2520that%2520perhaps%2520a%2520general%2520post%2520on%2520%25E2%2580%259Cthread%2520safety%25E2%2580%259D%2520was%2520in%2520order.%250D%250AStop%2520With%2520the%2520Quotes%2520Already%2521%250D%250AThe%2520astute%2520';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F%26amp%3Bbody%3DIntroduction%250D%250AFollowing%2520on%2520from%2520my%2520previous%2520post%2520about%2520a%2520%25E2%2580%259CThread%2520Safe%25E2%2580%259D%2520Dictionary%252C%2520and%2520the%2520subsequent%2520comment%2520from%2520Rajeesh%252C%2520made%2520me%2520think%2520that%2520perhaps%2520a%2520general%2520post%2520on%2520%25E2%2580%259Cthread%2520safety%25E2%2580%259D%2520was%2520in%2520order.%250D%250AStop%2520With%2520the%2520Quotes%2520Already%2521%250D%250AThe%2520astute%2520';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F26%252Fso-what-is-this-thread-safe-thing-anyway%252F%26amp%3Btitle%3DSo%2520What%2520Is%2520This%2520%2526ldquo%253BThread%2520Safe%2526rdquo%253B%2520Thing%2520Anyway%253F';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/concurrency' rel='tag' target='_blank'>concurrency</a>, <a class='technorati-link' href='http://technorati.com/tag/concurrentdictionary' rel='tag' target='_blank'>concurrentdictionary</a>, <a class='technorati-link' href='http://technorati.com/tag/csharp' rel='tag' target='_blank'>csharp</a>, <a class='technorati-link' href='http://technorati.com/tag/dictionary' rel='tag' target='_blank'>dictionary</a>, <a class='technorati-link' href='http://technorati.com/tag/locks' rel='tag' target='_blank'>locks</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2010/02/26/so-what-is-this-thread-safe-thing-anyway/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>“Thread safe” Dictionary(TKey,TValue)</title>
		<link>http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytvalue/</link>
		<comments>http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytvalue/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 18:56:58 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[concurrentdictionary]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[locks]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=264</guid>
		<description><![CDATA[Update : Based on a comment on this post I&#8217;ve added a follow up post that covers the question: What is This &#8220;Thread Safe&#8221; Thing Anyway?
Introduction
A pet project I’m currently working on requires the use of an internal Dictionary to store “registered” data, which is a pretty common requirement. For this particular project I’d like [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update : Based on a comment on this post I&#8217;ve added a follow up post that covers the question: <a href="http://www.grumpydev.com/2010/02/26/so-what-is-this-thread-safe-thing-anyway/" target="_blank">What is This &#8220;Thread Safe&#8221; Thing Anyway?</a></strong></p>
<h2>Introduction</h2>
<p>A pet project I’m currently working on requires the use of an internal Dictionary to store “registered” data, which is a pretty common requirement. For this particular project I’d like to at least *attempt* to make it “thread safe” on .NET 3.5, with an eye to moving it to the <a href="http://msdn.microsoft.com/en-us/library/dd287191(VS.100).aspx" target="_blank">ConcurrentDictionary</a> in .NET 4 which promises not only thread safety, but more granular locking to increase multi-threaded performance.</p>
<p>A simple enough task, but one that I’ve seen many people make mistakes implementing.</p>
<h2>Just Locking Writes?</h2>
<p>It’s obvious we need to do some kind of <a href="http://msdn.microsoft.com/en-us/library/ms228964(VS.95).aspx" target="_blank">syncronisation primitive</a> around our writes, but first impressions might make you think that read should be ok &#8211; especially if we stick to the preferred <a href="http://msdn.microsoft.com/en-us/library/zkw5c9ak(VS.85,classic).aspx" target="_blank">TryGetValue</a> pattern instead of “if it exists then get the value”:</p>
<pre class="brush: csharp; toolbar: false;">object myValue;

// This is obviously not thread safe.
// Something else can alter the collection
// between ContainsKey and reading the
// value.
if (dictionary.ContainsKey("Testing"))
{     myValue = dictionary["Testing"];
}

// Using TryGetValue looks safe though?
// Doesn't it?!
if (!dictionary.TryGetValue("Testing", out myValue))     throw new KeyNotFoundException();</pre>
<p>Unfortunately if we fire up <a href="http://www.red-gate.com/products/reflector/" target="_blank">Reflector</a>, and take a look at how TryGetValue is implemented, it’s pretty obvious it has exactly the same concurrency problem as the first method above:</p>
<pre class="brush: csharp; toolbar: false;">public bool TryGetValue(TKey key, out TValue value)
{
    int index = this.FindEntry(key);
    if (index &gt;= 0)
    {
        value = this.entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}</pre>
<h2>Ok, So I Will Lock Reads and Writes?</h2>
<p>The next obvious approach would be to find everywhere in our code where we access the Dictionary, for either reading or writing, and use a <a href="http://msdn.microsoft.com/en-us/library/ms228964(VS.95).aspx" target="_blank">syncronisation primitive</a>, such as <a href="http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx" target="_blank">lock</a>, to ensure we’re only accessing it from a single thread at any one time:</p>
<pre class="brush: csharp; toolbar: false;">private readonly object padlock = new object();
private readonly Dictionary&lt;string, object&gt; dictionary = new Dictionary&lt;string, object&gt;();

private void Test()
{
    object myValue;

    // Now we lock before we do anything
    lock (padlock)
    {
        if (dictionary.ContainsKey("Testing"))
        {
            myValue = dictionary["Testing"];
        }
    }

    lock (padlock)
    {
        if (!dictionary.TryGetValue("Testing", out myValue))
            throw new KeyNotFoundException();
    }
}</pre>
<p>Simple enough, but you’re relying on locking around every access, which is not only ugly, but also potentially prone to errors if you miss one. Also, once we move our code to .NET 4, and the new ConcurrentDictionary, we will have to go through the code and remove each lock in turn – pretty laborious!</p>
<h2>Composition, Composition, Composition!</h2>
<p>In this approach we wrap our nasty non-thread safe dictionary in our own class, expose the methods we want to use, and take any locks accordingly. This class only implements “array” access and TryGetValue, but is sufficient to show the approach:</p>
<pre class="brush: csharp; toolbar: false;">public class SafeDictionary&lt;TKey, TValue&gt;
{
    private readonly object _Padlock = new object();
    private readonly Dictionary&lt;TKey, TValue&gt; _Dictionary = new Dictionary&lt;TKey, TValue&gt;();

    public TValue this[TKey key]
    {
        get
        {
            lock (_Padlock)
            {
                return _Dictionary[key];
            }
        }
        set
        {
            lock (_Padlock)
            {
                _Dictionary[key] = value;
            }
        }
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        lock (_Padlock)
        {
            return _Dictionary.TryGetValue(key, out value);
        }
    }
}</pre>
<p>As we prevent any direct access to the Dictionary, and use our lock internally whenever we need to access it, we can now use our SafeDictionary in code without worrying about concurrency issues – both for reading and for writing!</p>
<h2>To .Net 4 ?</h2>
<p>As I mentioned earlier .Net 4 will be shipping with several “thread safe” collections, including a dictionary, in the new <a href="http://msdn.microsoft.com/en-us/library/system.collections.concurrent(VS.100).aspx" target="_blank">System.Collections.Concurrent namespace</a>. As we have our own SafeDictionary implementation we have a few options here:</p>
<ul>
<li>We could go through our code and replace all references to SafeDictionary with ConcurrentDictionary. We don’t have any locks in our main code so we could do this with a direct replacement.</li>
<li>We could alter our SafeDictionary to use a ConcurrentDictionary internally, and remove all of our internal locks.</li>
<li>If we don’t mind exposing extra methods we can remove all of the implementation from SafeDictionary and just derive it from ConcurrentDictionary:</li>
</ul>
<pre class="brush: csharp; toolbar: false;">public class SafeDictionary&lt;Tkey, TValue&gt; : ConcurrentDictionary&lt;Tkey, TValue&gt;
{
}</pre>
<h2>Conclusion</h2>
<p>Quite a long blog post for quite a simple issue, but even simple concurrency can be the source of mistakes and headaches. Once .NET 4 arrives with its <a href="http://msdn.microsoft.com/en-us/library/system.collections.concurrent(VS.100).aspx" target="_blank">concurrent collections</a>, <a href="http://www.microsoft.com/uk/msdn/nuggets/nugget/290/Intro-to-Parallel-Extensions-to-the-NET-Framework.aspx" target="_blank">parallel extensions</a> and <a href="http://www.danielmoth.com/Blog/2009/05/parallel-tasks-new-visual-studio-2010.html" target="_blank">parallel debugging options</a> hopefully at least *some* of this headache will go away.</p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Bannotation%3DUpdate%2520%253A%2520Based%2520on%2520a%2520comment%2520on%2520this%2520post%2520I%2527ve%2520added%2520a%2520follow%2520up%2520post%2520that%2520covers%2520the%2520question%253A%2520What%2520is%2520This%2520%2522Thread%2520Safe%2522%2520Thing%2520Anyway%253F%250D%250AIntroduction%250D%250AA%2520pet%2520project%2520I%25E2%2580%2599m%2520currently%2520working%2520on%2520requires%2520the%2520use%2520of%2520an%2520internal%2520Dictionary%2520to%2520store%2520%25E2%2580%259Creg';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Bbodytext%3DUpdate%2520%253A%2520Based%2520on%2520a%2520comment%2520on%2520this%2520post%2520I%2527ve%2520added%2520a%2520follow%2520up%2520post%2520that%2520covers%2520the%2520question%253A%2520What%2520is%2520This%2520%2522Thread%2520Safe%2522%2520Thing%2520Anyway%253F%250D%250AIntroduction%250D%250AA%2520pet%2520project%2520I%25E2%2580%2599m%2520currently%2520working%2520on%2520requires%2520the%2520use%2520of%2520an%2520internal%2520Dictionary%2520to%2520store%2520%25E2%2580%259Creg';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Bnotes%3DUpdate%2520%253A%2520Based%2520on%2520a%2520comment%2520on%2520this%2520post%2520I%2527ve%2520added%2520a%2520follow%2520up%2520post%2520that%2520covers%2520the%2520question%253A%2520What%2520is%2520This%2520%2522Thread%2520Safe%2522%2520Thing%2520Anyway%253F%250D%250AIntroduction%250D%250AA%2520pet%2520project%2520I%25E2%2580%2599m%2520currently%2520working%2520on%2520requires%2520the%2520use%2520of%2520an%2520internal%2520Dictionary%2520to%2520store%2520%25E2%2580%259Creg';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529%26amp%3Bbody%3DUpdate%2520%253A%2520Based%2520on%2520a%2520comment%2520on%2520this%2520post%2520I%2527ve%2520added%2520a%2520follow%2520up%2520post%2520that%2520covers%2520the%2520question%253A%2520What%2520is%2520This%2520%2522Thread%2520Safe%2522%2520Thing%2520Anyway%253F%250D%250AIntroduction%250D%250AA%2520pet%2520project%2520I%25E2%2580%2599m%2520currently%2520working%2520on%2520requires%2520the%2520use%2520of%2520an%2520internal%2520Dictionary%2520to%2520store%2520%25E2%2580%259Creg';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2010%252F02%252F25%252Fthread-safe-dictionarytkeytvalue%252F%26amp%3Btitle%3D%25E2%2580%259CThread%2520safe%25E2%2580%259D%2520Dictionary%2528TKey%252CTValue%2529';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/concurrency' rel='tag' target='_blank'>concurrency</a>, <a class='technorati-link' href='http://technorati.com/tag/concurrentdictionary' rel='tag' target='_blank'>concurrentdictionary</a>, <a class='technorati-link' href='http://technorati.com/tag/csharp' rel='tag' target='_blank'>csharp</a>, <a class='technorati-link' href='http://technorati.com/tag/dictionary' rel='tag' target='_blank'>dictionary</a>, <a class='technorati-link' href='http://technorati.com/tag/locks' rel='tag' target='_blank'>locks</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytvalue/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hotwire – A Remote Control Quick Launch Utility for LogMeIn</title>
		<link>http://www.grumpydev.com/2009/12/27/hotwire-a-remote-control-quick-launch-utility-for-logmein/</link>
		<comments>http://www.grumpydev.com/2009/12/27/hotwire-a-remote-control-quick-launch-utility-for-logmein/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 08:05:20 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[Hotwire]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[googlecode]]></category>
		<category><![CDATA[logmein]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=258</guid>
		<description><![CDATA[ 
Introduction
Hotwire is a project I started some time ago but never completed. It was designed to be a “quick launch” utility for remote controlling machines using the excellent LogMeIn service. While the better half was “enjoying” the Boxing Day sales I took it upon myself to finish the project. And by finish, I obviously [...]]]></description>
			<content:encoded><![CDATA[<h1><a href="http://www.grumpydev.com/wp-content/uploads/2009/12/hotwiresmall.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="hotwire-small" border="0" alt="hotwire-small" src="http://www.grumpydev.com/wp-content/uploads/2009/12/hotwiresmall_thumb.png" width="240" height="72" /></a> </h1>
<h2>Introduction</h2>
<p>Hotwire is a project I started <a href="http://www.grumpydev.com/2009/03/08/wpf-bootstrapping-notifyicon-shutdownmode-and-the-mysterious-vanishing-application/" target="_blank">some time ago</a> but never completed. It was designed to be a “quick launch” utility for remote controlling machines using the excellent <a href="http://www.logmein.com/" target="_blank">LogMeIn</a> service. While the better half was “enjoying” the Boxing Day sales I took it upon myself to finish the project. And by finish, I obviously mean a complete rewrite <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>What does it do?</h2>
<p>I’ve used LogMeIn for quite a while now, and it’s an excellent service, but 99% of the time I just want to get straight to the desktop of the machine I’m connecting to and Hotwire is designed to let me do just that.</p>
<p>The application itself is written using WPF and consists of two parts; the launcher, which sits in the task tray, and the main application. The launcher provides machine configuration and quick launch options for connecting to remote machines. The main application is just a single window (containing a WPF <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.aspx" target="_blank">WebBrowser</a> control) that connects to LogMeIn and does some jiggery pokery to get you directly to your machine desktop.</p>
<h2>More Information</h2>
<p>The project is up on Google Code at <a href="http://code.google.com/p/hotwire/">http://code.google.com/p/hotwire/</a> – I normally prefer to use CodePlex, but the Hotwire name was already taken <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  The Google code site contains a downloadable installer, and the source code should anyone be interested.</p>
<h2>Screenshots</h2>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/12/Tray.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Tray" border="0" alt="Tray" src="http://www.grumpydev.com/wp-content/uploads/2009/12/Tray_thumb.png" width="244" height="133" /></a> </p>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/12/Configuration.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Configuration" border="0" alt="Configuration" src="http://www.grumpydev.com/wp-content/uploads/2009/12/Configuration_thumb.png" width="404" height="404" /></a></p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Bannotation%3D%2520%2520%2520Introduction%2520%2520Hotwire%2520is%2520a%2520project%2520I%2520started%2520some%2520time%2520ago%2520but%2520never%2520completed.%2520It%2520was%2520designed%2520to%2520be%2520a%2520%25E2%2580%259Cquick%2520launch%25E2%2580%259D%2520utility%2520for%2520remote%2520controlling%2520machines%2520using%2520the%2520excellent%2520LogMeIn%2520service.%2520While%2520the%2520better%2520half%2520was%2520%25E2%2580%259Cenjoying%25E2%2580%259D%2520the%2520Bo';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Bbodytext%3D%2520%2520%2520Introduction%2520%2520Hotwire%2520is%2520a%2520project%2520I%2520started%2520some%2520time%2520ago%2520but%2520never%2520completed.%2520It%2520was%2520designed%2520to%2520be%2520a%2520%25E2%2580%259Cquick%2520launch%25E2%2580%259D%2520utility%2520for%2520remote%2520controlling%2520machines%2520using%2520the%2520excellent%2520LogMeIn%2520service.%2520While%2520the%2520better%2520half%2520was%2520%25E2%2580%259Cenjoying%25E2%2580%259D%2520the%2520Bo';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Bnotes%3D%2520%2520%2520Introduction%2520%2520Hotwire%2520is%2520a%2520project%2520I%2520started%2520some%2520time%2520ago%2520but%2520never%2520completed.%2520It%2520was%2520designed%2520to%2520be%2520a%2520%25E2%2580%259Cquick%2520launch%25E2%2580%259D%2520utility%2520for%2520remote%2520controlling%2520machines%2520using%2520the%2520excellent%2520LogMeIn%2520service.%2520While%2520the%2520better%2520half%2520was%2520%25E2%2580%259Cenjoying%25E2%2580%259D%2520the%2520Bo';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn%26amp%3Bbody%3D%2520%2520%2520Introduction%2520%2520Hotwire%2520is%2520a%2520project%2520I%2520started%2520some%2520time%2520ago%2520but%2520never%2520completed.%2520It%2520was%2520designed%2520to%2520be%2520a%2520%25E2%2580%259Cquick%2520launch%25E2%2580%259D%2520utility%2520for%2520remote%2520controlling%2520machines%2520using%2520the%2520excellent%2520LogMeIn%2520service.%2520While%2520the%2520better%2520half%2520was%2520%25E2%2580%259Cenjoying%25E2%2580%259D%2520the%2520Bo';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F12%252F27%252Fhotwire-a-remote-control-quick-launch-utility-for-logmein%252F%26amp%3Btitle%3DHotwire%2520%2526ndash%253B%2520A%2520Remote%2520Control%2520Quick%2520Launch%2520Utility%2520for%2520LogMeIn';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/googlecode' rel='tag' target='_blank'>googlecode</a>, <a class='technorati-link' href='http://technorati.com/tag/Hotwire' rel='tag' target='_blank'>Hotwire</a>, <a class='technorati-link' href='http://technorati.com/tag/logmein' rel='tag' target='_blank'>logmein</a>, <a class='technorati-link' href='http://technorati.com/tag/WPF' rel='tag' target='_blank'>WPF</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2009/12/27/hotwire-a-remote-control-quick-launch-utility-for-logmein/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF RichTextBox Subscript and Superscript Without Font Restrictions</title>
		<link>http://www.grumpydev.com/2009/11/05/wpf-richtextbox-subscript-and-superscript-without-font-restrictions/</link>
		<comments>http://www.grumpydev.com/2009/11/05/wpf-richtextbox-subscript-and-superscript-without-font-restrictions/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 21:30:39 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[WPF]]></category>
		<category><![CDATA[opentype]]></category>
		<category><![CDATA[richtextbox]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=248</guid>
		<description><![CDATA[Introduction
One of the most bizarre limitation of the WPF RichTextBox is its hit and miss support for subscript and superscript in text. Although you can set the style quite easily using appropriate command, in order for this property to actually alter the appearance of the text the font needs to be OpenType, and come with [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>One of the most bizarre limitation of the WPF <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx" target="_blank">RichTextBox</a> is its hit and miss support for subscript and superscript in text. Although you can set the style quite easily using <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.editingcommands.togglesuperscript.aspx" target="_blank">appropriate command</a>, in order for this property to actually alter the appearance of the text the font needs to be OpenType, and <a href="http://msdn.microsoft.com/en-us/library/ms745109.aspx#variants" target="_blank">come with a Subscript/Superscript variant</a>, which the vast majority of fonts do not. Obviously in a control that’s designed for user input, restricting what fonts can be used in this way is far from ideal.</p>
<h2>An Alternative Approach</h2>
<p>Having spent some time poking around inside <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx" target="_blank">RichTextBox</a> I would strongly recommend that you don’t. Seriously. The code may well make you physically sick. In the past I have tried to use <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.textrange.applypropertyvalue.aspx" target="_blank">TextRange.ApplyPropertyValue</a>, which takes a normal DependencyProperty, to attach my own property to a piece of text. You’d imagine this would be pretty straightforward, especially as attaching properties to other types is a fairly fundamental part of WPF, but unfortunately there’s a particularly <em>lovely</em> piece of code that checks to see if the DependencyProperty is on a predefined “allowed” list, and thows an exception if it isn’t. While this chunk of code scuppered my ideas in the past, it did provide a useful place to look for an alternative way to create Subscript and Superscript text.</p>
<p>One of the properties that we are “allowed” to apply to text is <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.inline.baselinealignment.aspx" target="_blank">Inline.BaselineAlignmentProperty</a> which takes its values from the <a href="http://msdn.microsoft.com/en-us/library/system.windows.baselinealignment.aspx" target="_blank">BaselineAlignment enumeration</a> which includes the following values:</p>
<ul>
<li><strong>Top</strong>       <br />A baseline that is aligned to the upper edge of the containing box. </li>
<li><strong>Center</strong>       <br />A baseline that is aligned to the center of the containing box. </li>
<li><strong>Bottom</strong>       <br />A baseline that is aligned at the lower edge of the containing box. </li>
<li><strong>Baseline</strong>       <br />A baseline that is aligned at the actual baseline of the containing box. </li>
<li><strong>TextTop</strong>       <br />A baseline that is aligned at the upper edge of the text baseline. </li>
<li><strong>TextBottom</strong>       <br />A baseline that is aligned at the lower edge of the text baseline. </li>
<li><strong>Subscript</strong>       <br />A baseline that is aligned at the subscript position of the containing box. </li>
<li><strong>Superscript</strong>       <br />A baseline that is aligned at the superscript position of the containing box. </li>
</ul>
<p>Subscript and Superscript look exactly like what we want, and amazingly, they actually work <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  To demonstrate the technique I’ve created two simple extension methods that toggle either Sub or Superscript on the selected text:</p>
<pre class="c#:nocontrols" name="code">/// &lt;summary&gt;
/// Toggle Superscript for the currently selected text in a RichTextBox. Does not require the font to be OpenType or have a Superscript font style.
///
/// Doesn't attempt to change/restore the size of the font, just moves the baseline.
/// &lt;/summary&gt;
/// &lt;param name=&quot;richTextBox&quot;&gt;RichTextBox with selected text&lt;/param&gt;
public static void ToggleSelectionSuperscript(this RichTextBox richTextBox)
{
    var currentAlignment = richTextBox.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

    BaselineAlignment newAlignment = ((BaselineAlignment)currentAlignment == BaselineAlignment.Superscript) ? BaselineAlignment.Baseline : BaselineAlignment.Superscript;
    richTextBox.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);
}</pre>
<p>The code checks the current value of the BaselineAlignmentProperty and toggles the value as appropriate. I’ve made no attempt to adjust font size, or do anything clever, so it does look a <em>little</em> goofy, but it proves the concept. The demo application also includes the XAML content of the RichTextBox document so you can see exactly what content it’s producing:</p>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/11/RichTextBoxSubSuperscriptScreenshot.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="RichTextBoxSubSuperscriptScreenshot" border="0" alt="RichTextBoxSubSuperscriptScreenshot" src="http://www.grumpydev.com/wp-content/uploads/2009/11/RichTextBoxSubSuperscriptScreenshot_thumb.png" width="244" height="173" /></a> </p>
<p>And that’s that, hope it helps someone out <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  You can grab the sample demo from the link below:</p>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/11/RichTextBoxSubSuperscript.zip" target="_blank">RichTextBoxSubSuperscript.zip</a></p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Bannotation%3DIntroduction%2520%2520One%2520of%2520the%2520most%2520bizarre%2520limitation%2520of%2520the%2520WPF%2520RichTextBox%2520is%2520its%2520hit%2520and%2520miss%2520support%2520for%2520subscript%2520and%2520superscript%2520in%2520text.%2520Although%2520you%2520can%2520set%2520the%2520style%2520quite%2520easily%2520using%2520appropriate%2520command%252C%2520in%2520order%2520for%2520this%2520property%2520to%2520actually%2520a';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Bbodytext%3DIntroduction%2520%2520One%2520of%2520the%2520most%2520bizarre%2520limitation%2520of%2520the%2520WPF%2520RichTextBox%2520is%2520its%2520hit%2520and%2520miss%2520support%2520for%2520subscript%2520and%2520superscript%2520in%2520text.%2520Although%2520you%2520can%2520set%2520the%2520style%2520quite%2520easily%2520using%2520appropriate%2520command%252C%2520in%2520order%2520for%2520this%2520property%2520to%2520actually%2520a';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Bnotes%3DIntroduction%2520%2520One%2520of%2520the%2520most%2520bizarre%2520limitation%2520of%2520the%2520WPF%2520RichTextBox%2520is%2520its%2520hit%2520and%2520miss%2520support%2520for%2520subscript%2520and%2520superscript%2520in%2520text.%2520Although%2520you%2520can%2520set%2520the%2520style%2520quite%2520easily%2520using%2520appropriate%2520command%252C%2520in%2520order%2520for%2520this%2520property%2520to%2520actually%2520a';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions%26amp%3Bbody%3DIntroduction%2520%2520One%2520of%2520the%2520most%2520bizarre%2520limitation%2520of%2520the%2520WPF%2520RichTextBox%2520is%2520its%2520hit%2520and%2520miss%2520support%2520for%2520subscript%2520and%2520superscript%2520in%2520text.%2520Although%2520you%2520can%2520set%2520the%2520style%2520quite%2520easily%2520using%2520appropriate%2520command%252C%2520in%2520order%2520for%2520this%2520property%2520to%2520actually%2520a';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F11%252F05%252Fwpf-richtextbox-subscript-and-superscript-without-font-restrictions%252F%26amp%3Btitle%3DWPF%2520RichTextBox%2520Subscript%2520and%2520Superscript%2520Without%2520Font%2520Restrictions';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/opentype' rel='tag' target='_blank'>opentype</a>, <a class='technorati-link' href='http://technorati.com/tag/richtextbox' rel='tag' target='_blank'>richtextbox</a>, <a class='technorati-link' href='http://technorati.com/tag/workaround' rel='tag' target='_blank'>workaround</a>, <a class='technorati-link' href='http://technorati.com/tag/WPF' rel='tag' target='_blank'>WPF</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2009/11/05/wpf-richtextbox-subscript-and-superscript-without-font-restrictions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Localising WPF Applications Using RESX Files and Standard Data Binding (Without a MarkupExtension)</title>
		<link>http://www.grumpydev.com/2009/09/08/localising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension/</link>
		<comments>http://www.grumpydev.com/2009/09/08/localising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 20:04:01 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[WPF]]></category>
		<category><![CDATA[localisation]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[resourcemanager]]></category>
		<category><![CDATA[resx]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=239</guid>
		<description><![CDATA[Introduction
Localisation is something everyone should really care about. Creating your applications, or websites, in a manner that can be easily localised for different languages and cultures is not only “good practice”, but it may also provide additional opportunities.
Luckily the .NET framework, and WPF, has rich support for localisation, with WPF even having “baked in” support [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Localisation is something everyone should really care about. Creating your applications, or websites, in a manner that can be easily localised for different languages and cultures is not only “good practice”, but it may also provide additional opportunities.</p>
<p>Luckily the .NET framework, and WPF, has rich support for localisation, with WPF even having “baked in” support for switching flow direction for <a href="http://en.wikipedia.org/wiki/Bi-directional_text" target="_blank">right to left languages</a>. On top of that <a href="http://www.west-wind.com/weblog/" target="_blank">Rick Strahl</a> and <a href="http://www.dasblonde.net/" target="_blank">Michele Leroux Bustamante</a> compiled an excellent guidance document detailing several technique for localising WPF applications. The documentation, along with sample code, can be found in the <a href="http://wpflocalization.codeplex.com/" target="_blank">WPF Localisation Guidance</a> project on CodePlex.</p>
<p>The document discusses several techniques for localising applications using RESX (resource) files, which is my preferred approach; but each of the techniques has its drawbacks:</p>
<ul>
<li><strong>Static Binding</strong>. Simple and easy, but lacks support for dynamically switching culture. </li>
<li><strong>Attached Properties</strong>. Look powerful, but lacks support for value convertors and it’s a bit inefficient. </li>
<li><strong>Markup Extension</strong>. A new instance of the helper (complete with event wireup for locale switching) is created for every control, which doesn’t sound ideal and may lead to memory leaks. </li>
</ul>
<p>All of the techniques are perfectly workable solutions, but with Binding and INotifyPropertyChanged WPF already contains a powerful mechanism for mapping and automatically updating UI elements with data; surely there’s some way we can leverage those? My goal was to attempt to find a way to localise an application with the following criteria:</p>
<ul>
<li>Use the standard Binding syntax so we can support value convertors. </li>
<li>No complicated markup extensions. </li>
<li>Provide a mechanism for code to “register” resources that can be consumed anywhere in the application, even from other PRISM modules. </li>
<li>Be able to cleanly switch locales, without restarting the application or closing/reopening screens. </li>
<li>Support the design experience with a minimum of fall back values when in design mode. </li>
</ul>
<h2>The Result – Localisation Using Binding</h2>
<p>If you just want to see the code, there’s a basic implementation, and a <a href="http://msdn.microsoft.com/en-us/library/dd458809.aspx" target="_blank">PRISM</a> demonstration, at the end of the article. Both implementations use the same basic “moving parts”:</p>
<h3></h3>
<h3>LocalisationHelper</h3>
<p>In essence this is our ViewModel. There are two key pieces of code here, first being:</p>
<pre class="c#:nocontrols" name="code">public string this[string Key]
{
    get
    {
        if (!validKey(Key))
            throw new ArgumentException(@&quot;Key is not in the valid [ManagerName].[ResourceKey] format&quot;);

        if (DesignHelpers.IsInDesignModeStatic)
            throw new Exception(&quot;Design mode is not supported&quot;);

        return _resourceManager.GetResourceString(GetManagerKey(Key), GetResourceKey(Key));
    }
}</pre>
<p>This allows us to bind elements to the LocalisationHelper and provide a “key” which will be used to lookup the correct resource manager and resource string. Our binding uses a little known syntax that looks like this (take note of the initial “.”):</p>
<pre>{Binding Path=.[MyResourceManager.MyResourceString]}</pre>
<p>To provide design support we throw an exception if we detect design mode (using code from Laurent Bugnion’s <a href="http://www.galasoft.ch/mvvm/getstarted/" target="_blank">MVVM Light Toolkit</a>) so the FallbackValue can be used instead. I’m not too keep on throwing an exception, but I couldn’t see a cleaner way to “fail” the binding.</p>
<p>The other important code hooks an event that fires when the locale changes, and fires a NotifyPropertyChangedEvent with an empty property string. This triggers a refresh for all controls that have bindings to the LocalisationHelper.</p>
<h3>ResourceManagerService</h3>
<p>The ResourceManagerService provides several functions:</p>
<ul>
<li>The ability to register <a href="http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.aspx" target="_blank">ResourceManagers</a> – these are automatically generated by Visual Studio when you create RESX files and are used to load the locale specific strings. </li>
<li>Retrieve a resource string from a given <a href="http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.aspx" target="_blank">ResourceManager</a>. </li>
<li>Get and set the current locale. A locale consists of an IETF language tag (such as en-GB) and a boolean to indicate whether the locale uses a <a href="http://en.wikipedia.org/wiki/Bi-directional_text" target="_blank">right to left flow direction</a>. </li>
<li>A event that is fired when the locale changes. This is hooked by the LocalisationHelper, for firing <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx" target="_blank">PropertyChanged</a> events, and also by the main Window which uses the right to left flag to set the flow direction. </li>
</ul>
<h2>Give Me The Code Already!</h2>
<p>There are two samples attached. The first is a simple application that uses a static ResourceManagerService that shows the basic implementation. The second is a <a href="http://msdn.microsoft.com/en-us/library/dd458809.aspx" target="_blank">PRISM</a> based application that uses the container/service locator, EventAggregator, weak references, and several different modules to give a more “advanced” example.</p>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/09/ResourceTest.zip" target="_blank">ResourceTest.zip</a></p>
<p><a href="http://www.grumpydev.com/wp-content/uploads/2009/09/PRISMResourceTest.zip" target="_blank">PRISMResourceTest.zip</a></p>
<h2>Conclusion</h2>
<p>I haven’t yet used this solution in anger, but it certainly seems to “tick all the boxes” from my initial requirements. Comments, suggestions, criticisms and flames are welcomed <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Bannotation%3DIntroduction%2520%2520Localisation%2520is%2520something%2520everyone%2520should%2520really%2520care%2520about.%2520Creating%2520your%2520applications%252C%2520or%2520websites%252C%2520in%2520a%2520manner%2520that%2520can%2520be%2520easily%2520localised%2520for%2520different%2520languages%2520and%2520cultures%2520is%2520not%2520only%2520%25E2%2580%259Cgood%2520practice%25E2%2580%259D%252C%2520but%2520it%2520may%2520also%2520provide';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Bbodytext%3DIntroduction%2520%2520Localisation%2520is%2520something%2520everyone%2520should%2520really%2520care%2520about.%2520Creating%2520your%2520applications%252C%2520or%2520websites%252C%2520in%2520a%2520manner%2520that%2520can%2520be%2520easily%2520localised%2520for%2520different%2520languages%2520and%2520cultures%2520is%2520not%2520only%2520%25E2%2580%259Cgood%2520practice%25E2%2580%259D%252C%2520but%2520it%2520may%2520also%2520provide';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Bnotes%3DIntroduction%2520%2520Localisation%2520is%2520something%2520everyone%2520should%2520really%2520care%2520about.%2520Creating%2520your%2520applications%252C%2520or%2520websites%252C%2520in%2520a%2520manner%2520that%2520can%2520be%2520easily%2520localised%2520for%2520different%2520languages%2520and%2520cultures%2520is%2520not%2520only%2520%25E2%2580%259Cgood%2520practice%25E2%2580%259D%252C%2520but%2520it%2520may%2520also%2520provide';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529%26amp%3Bbody%3DIntroduction%2520%2520Localisation%2520is%2520something%2520everyone%2520should%2520really%2520care%2520about.%2520Creating%2520your%2520applications%252C%2520or%2520websites%252C%2520in%2520a%2520manner%2520that%2520can%2520be%2520easily%2520localised%2520for%2520different%2520languages%2520and%2520cultures%2520is%2520not%2520only%2520%25E2%2580%259Cgood%2520practice%25E2%2580%259D%252C%2520but%2520it%2520may%2520also%2520provide';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F08%252Flocalising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension%252F%26amp%3Btitle%3DLocalising%2520WPF%2520Applications%2520Using%2520RESX%2520Files%2520and%2520Standard%2520Data%2520Binding%2520%2528Without%2520a%2520MarkupExtension%2529';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/localisation' rel='tag' target='_blank'>localisation</a>, <a class='technorati-link' href='http://technorati.com/tag/localization' rel='tag' target='_blank'>localization</a>, <a class='technorati-link' href='http://technorati.com/tag/resourcemanager' rel='tag' target='_blank'>resourcemanager</a>, <a class='technorati-link' href='http://technorati.com/tag/resx' rel='tag' target='_blank'>resx</a>, <a class='technorati-link' href='http://technorati.com/tag/WPF' rel='tag' target='_blank'>WPF</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2009/09/08/localising-wpf-applications-using-resx-files-and-standard-data-binding-without-a-markupextension/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>System.OutOfMemoryException Gotcha Using Clipboard.GetData in WPF</title>
		<link>http://www.grumpydev.com/2009/09/05/system-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf/</link>
		<comments>http://www.grumpydev.com/2009/09/05/system-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 16:07:08 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[Rambling]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[clipboard]]></category>
		<category><![CDATA[OutOfMemoryException]]></category>
		<category><![CDATA[System.OutOfMemoryException]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=229</guid>
		<description><![CDATA[Introduction
Consider the following simple class for managing storage and retrieval of custom classes in the Windows Clipboard using WPF:
using System;
using System.Windows;

namespace ClipboardTest.Services
{
    public class ClipboardService : IClipboardService
    {
        public bool ContainsData&#60;T&#62;() where T:class
        {
  [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Consider the following simple class for managing storage and retrieval of custom classes in the Windows Clipboard using WPF:</p>
<pre class="c#:nocontrols" name="code">using System;
using System.Windows;

namespace ClipboardTest.Services
{
    public class ClipboardService : IClipboardService
    {
        public bool ContainsData&lt;T&gt;() where T:class
        {
            return Clipboard.ContainsData(typeof(T).ToString());
        }

        public void SetData&lt;T&gt;(T data) where T:class
        {
            Clipboard.SetData(typeof(T).ToString(), data);
        }

        public T GetData&lt;T&gt;() where T : class
        {
            return Clipboard.GetData(typeof(T).ToString()) as T;
        }
    }
}</pre>
<p>Simple stuff, but it lets me abstract the clipboard away and remove the usual “magic string” approach for clipboard types.</p>
<p>Now consider the following basic tests:</p>
<pre class="c#:nocontrols" name="code">using ClipboardTest.Services;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ClipboardTest.Test.Services
{
    public class TestPayload
    {
        public string Data { get; set; }
    }

    [TestClass]
    public class ClipboardServiceTests
    {
        [TestMethod]
        public void SetData_CustomClass_ClipboardContainsInstanceOfClass()
        {
            string data = @&quot;More Cowbell&quot;;
            var clipboardService = new ClipboardService();

            clipboardService.SetData&lt;TestPayload&gt;(new TestPayload() { Data = data });

            Assert.IsTrue(clipboardService.ContainsData&lt;TestPayload&gt;());
        }

        [TestMethod]
        public void SetDataGetData_CustomClass_ReturnsEquivilantClass()
        {
            string data = @&quot;More Cowbell&quot;;
            var clipboardService = new ClipboardService();

            clipboardService.SetData&lt;TestPayload&gt;(new TestPayload() { Data = data });
            var output = clipboardService.GetData&lt;TestPayload&gt;();

            Assert.IsNotNull(output);
            Assert.AreEqual(data, output.Data);
        }
    }
}</pre>
<p>Again, all very simple. The first test checks to make sure that the class gets stored onto the clipboard, and the second checks to see if the class we get back off the clipboard is the same as the one we put in.</p>
<p>The more astute among you have probably spotted the problem in the test code already, but the resultant symptoms are a little confusing.</p>
<h2>System.OutOfMemoryException?</h2>
<p>When we run the tests the first test runs absolutely fine, but the second test crashes out with a <a href="http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx" target="_blank">System.OutOfMemoryException</a>. A bit more digging showed that storing and retrieving standard types such as strings, ints etc all worked fine, but my own class was throwing an exception.</p>
<p>Checking good old MSDN threw up the following statement:</p>
<blockquote>
<p>An object must be serializable for it to be put on the Clipboard.</p>
</blockquote>
<p>Seeing as I had stupidly forgotten to add the <a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" target="_blank">SerializableAttribute</a> to the TestPayload class that definitely explained why things weren’t working as I expected; but it didn’t really explain the actual behaviour I was seeing. Another quote from MSDN, but from the WinForms documentation, stated:</p>
<blockquote>
<p>If you pass a non-serializable object to a Clipboard method, the method will fail without throwing an exception.</p>
</blockquote>
<p>So from that I would expect SetData to silently fail, and for nothing to be on the clipboard. However the first test above clearly shows that the clipboard at least <em>thinks</em> that <strong>something</strong> of our specified type has been added to the clipboard – it just throws an exception when we try and retrieve it again. Marking the payload class as serializable did fix the issue, but the behaviour I was seeing certainly didn’t make that obvious!</p>
<p>Just out of interest I tested the same code using the WinForms Clipboard class, which looks to all intents and purposes exactly the same as the WPF one, and that did fail silently and returned <em>null</em> from GetData.</p>
<h2>Conclusion</h2>
<p>So, after all that rambling, the conclusion is that if you are working with the Clipboard in WPF and you are getting <a href="http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx" target="_blank">System.OutOfMemoryException</a>s that don’t seem to make any sense, then you’ve probably forgotten to add the <a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" target="_blank">SerializableAttribute</a> to whatever class you placed on the Clipboard.</p>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Bannotation%3DIntroduction%2520%2520Consider%2520the%2520following%2520simple%2520class%2520for%2520managing%2520storage%2520and%2520retrieval%2520of%2520custom%2520classes%2520in%2520the%2520Windows%2520Clipboard%2520using%2520WPF%253A%2520%2520using%2520System%253B%250D%250Ausing%2520System.Windows%253B%250D%250A%250D%250Anamespace%2520ClipboardTest.Services%250D%250A%257B%250D%250A%2520%2520%2520%2520public%2520class%2520ClipboardService';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Bbodytext%3DIntroduction%2520%2520Consider%2520the%2520following%2520simple%2520class%2520for%2520managing%2520storage%2520and%2520retrieval%2520of%2520custom%2520classes%2520in%2520the%2520Windows%2520Clipboard%2520using%2520WPF%253A%2520%2520using%2520System%253B%250D%250Ausing%2520System.Windows%253B%250D%250A%250D%250Anamespace%2520ClipboardTest.Services%250D%250A%257B%250D%250A%2520%2520%2520%2520public%2520class%2520ClipboardService';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Bnotes%3DIntroduction%2520%2520Consider%2520the%2520following%2520simple%2520class%2520for%2520managing%2520storage%2520and%2520retrieval%2520of%2520custom%2520classes%2520in%2520the%2520Windows%2520Clipboard%2520using%2520WPF%253A%2520%2520using%2520System%253B%250D%250Ausing%2520System.Windows%253B%250D%250A%250D%250Anamespace%2520ClipboardTest.Services%250D%250A%257B%250D%250A%2520%2520%2520%2520public%2520class%2520ClipboardService';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF%26amp%3Bbody%3DIntroduction%2520%2520Consider%2520the%2520following%2520simple%2520class%2520for%2520managing%2520storage%2520and%2520retrieval%2520of%2520custom%2520classes%2520in%2520the%2520Windows%2520Clipboard%2520using%2520WPF%253A%2520%2520using%2520System%253B%250D%250Ausing%2520System.Windows%253B%250D%250A%250D%250Anamespace%2520ClipboardTest.Services%250D%250A%257B%250D%250A%2520%2520%2520%2520public%2520class%2520ClipboardService';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F09%252F05%252Fsystem-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf%252F%26amp%3Btitle%3DSystem.OutOfMemoryException%2520Gotcha%2520Using%2520Clipboard.GetData%2520in%2520WPF';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/clipboard' rel='tag' target='_blank'>clipboard</a>, <a class='technorati-link' href='http://technorati.com/tag/OutOfMemoryException' rel='tag' target='_blank'>OutOfMemoryException</a>, <a class='technorati-link' href='http://technorati.com/tag/System.OutOfMemoryException' rel='tag' target='_blank'>System.OutOfMemoryException</a>, <a class='technorati-link' href='http://technorati.com/tag/WPF' rel='tag' target='_blank'>WPF</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2009/09/05/system-outofmemoryexception-gotcha-using-clipboard-getdata-in-wpf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bindings Not Updating in WPF / Silverlight? Common Mistakes</title>
		<link>http://www.grumpydev.com/2009/08/26/bindings-not-updating-in-wpf-silverlight-common-mistakes/</link>
		<comments>http://www.grumpydev.com/2009/08/26/bindings-not-updating-in-wpf-silverlight-common-mistakes/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 07:07:39 +0000</pubDate>
		<dc:creator>srobbins</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[inotifypropertychanged]]></category>

		<guid isPermaLink="false">http://www.grumpydev.com/?p=225</guid>
		<description><![CDATA[Introduction
Yesterday I was working on a small prototype, which I will be blogging about shortly, and ran across the common problem of my bindings not updating. A very common problem, and one that’s usually a very simple fix once you’ve tracked it down.
Yes, I’m an Idiot!
Normally my ViewModels inherit from my ViewModelBase base class, which [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Yesterday I was working on a small prototype, which I will be blogging about shortly, and ran across the common problem of my bindings not updating. A very common problem, and one that’s usually a very simple fix once you’ve tracked it down.</p>
<h2>Yes, I’m an Idiot!</h2>
<p>Normally my ViewModels inherit from my ViewModelBase base class, which provides a RaisePropertyChanged method and, when in debug mode, uses reflection to check if the property name is valid. Now I’d recently refactored the code so this particular ViewModel wasn’t using the base class, so my first instinct was that I’d simply mistyped the property name magic string in the event – but that was all fine.</p>
<p>I threw in a few breakpoints and I could see my ViewModel was changing, I could see the OnPropertyChanged method being hit, but there didn’t seem to be any listeners and as a result my UI was just ignoring the changes.</p>
<p>After a few minutes of head scratching I noticed that although my class was firing the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx" target="_blank">PropertyChanged</a> event correctly, I hadn’t added <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx" target="_blank">INotifyPropertyChanged</a> to my class declaration when I removed the base class! So although I was firing an event that <strong>looked</strong> like <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx" target="_blank">INotifyPropertyChanged.PropertyChanged</a>, I was actually just firing my own event with the same name <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Conclusion</h2>
<p>So there you have it, I’m an idiot <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  The moral of the story is, when your bindings aren’t working check the obvious:</p>
<ol>
<li>The property name is correct. A base class that checks this in debug mode can be useful, or failing that, watch the Output window.</li>
<li>Check you are actually implementing <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx" target="_blank">INotifyPropertyChanged</a> and not just firing events that happen to have the same name <img src='http://www.grumpydev.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ol>



Share:


	<a rel="nofollow" id="twitter" target="_blank" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%2520-%2520http%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F';" title="Twitter"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetkicks" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.dotnetkicks.com%2Fkick%2F%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes';" title="DotNetKicks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dotnetkicks.png" title="DotNetKicks" alt="DotNetKicks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="dotnetshoutout" target="_blank" href="javascript:window.location='http%3A%2F%2Fdotnetshoutout.com%2FSubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes';" title="DotNetShoutout"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/dnso.png" title="DotNetShoutout" alt="DotNetShoutout" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Bannotation%3DIntroduction%2520%2520Yesterday%2520I%2520was%2520working%2520on%2520a%2520small%2520prototype%252C%2520which%2520I%2520will%2520be%2520blogging%2520about%2520shortly%252C%2520and%2520ran%2520across%2520the%2520common%2520problem%2520of%2520my%2520bindings%2520not%2520updating.%2520A%2520very%2520common%2520problem%252C%2520and%2520one%2520that%25E2%2580%2599s%2520usually%2520a%2520very%2520simple%2520fix%2520once%2520you%25E2%2580%2599ve%2520tracked';" title="Google Bookmarks"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" target="_blank" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Bbodytext%3DIntroduction%2520%2520Yesterday%2520I%2520was%2520working%2520on%2520a%2520small%2520prototype%252C%2520which%2520I%2520will%2520be%2520blogging%2520about%2520shortly%252C%2520and%2520ran%2520across%2520the%2520common%2520problem%2520of%2520my%2520bindings%2520not%2520updating.%2520A%2520very%2520common%2520problem%252C%2520and%2520one%2520that%25E2%2580%2599s%2520usually%2520a%2520very%2520simple%2520fix%2520once%2520you%25E2%2580%2599ve%2520tracked';" title="Digg"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" target="_blank" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Bnotes%3DIntroduction%2520%2520Yesterday%2520I%2520was%2520working%2520on%2520a%2520small%2520prototype%252C%2520which%2520I%2520will%2520be%2520blogging%2520about%2520shortly%252C%2520and%2520ran%2520across%2520the%2520common%2520problem%2520of%2520my%2520bindings%2520not%2520updating.%2520A%2520very%2520common%2520problem%252C%2520and%2520one%2520that%25E2%2580%2599s%2520usually%2520a%2520very%2520simple%2520fix%2520once%2520you%25E2%2580%2599ve%2520tracked';" title="del.icio.us"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="live" target="_blank" href="javascript:window.location='https%3A%2F%2Ffavorites.live.com%2Fquickadd.aspx%3Fmarklet%3D1%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes';" title="Live"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/live.png" title="Live" alt="Live" class="sociable-hovers" /></a>
	<a rel="nofollow" id="technorati" target="_blank" href="javascript:window.location='http%3A%2F%2Ftechnorati.com%2Ffaves%3Fadd%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F';" title="Technorati"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes';" title="StumbleUpon"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>
	<a rel="nofollow" id="email" target="_blank" href="javascript:window.location='mailto%3A%3Fsubject%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Bbody%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F';" title="E-mail this story to a friend!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/email_link.png" title="E-mail this story to a friend!" alt="E-mail this story to a friend!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="netvibes" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.netvibes.com%2Fshare%3Ftitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Burl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F';" title="Netvibes"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/netvibes.png" title="Netvibes" alt="Netvibes" class="sociable-hovers" /></a>
	<a rel="nofollow" id="ping.fm" target="_blank" href="javascript:window.location='http%3A%2F%2Fping.fm%2Fref%2F%3Flink%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes%26amp%3Bbody%3DIntroduction%2520%2520Yesterday%2520I%2520was%2520working%2520on%2520a%2520small%2520prototype%252C%2520which%2520I%2520will%2520be%2520blogging%2520about%2520shortly%252C%2520and%2520ran%2520across%2520the%2520common%2520problem%2520of%2520my%2520bindings%2520not%2520updating.%2520A%2520very%2520common%2520problem%252C%2520and%2520one%2520that%25E2%2580%2599s%2520usually%2520a%2520very%2520simple%2520fix%2520once%2520you%25E2%2580%2599ve%2520tracked';" title="Ping.fm"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/ping.png" title="Ping.fm" alt="Ping.fm" class="sociable-hovers" /></a>
	<a rel="nofollow" id="print" target="_blank" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" target="_blank" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.grumpydev.com%252F2009%252F08%252F26%252Fbindings-not-updating-in-wpf-silverlight-common-mistakes%252F%26amp%3Btitle%3DBindings%2520Not%2520Updating%2520in%2520WPF%2520%252F%2520Silverlight%253F%2520Common%2520Mistakes';" title="Reddit"><img src="http://www.grumpydev.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>


<br/><br/>
<!-- start wp-tags-to-technorati 1.01 -->

<p class='technorati-tags'>Technorati Tags: <a class='technorati-link' href='http://technorati.com/tag/binding' rel='tag' target='_blank'>binding</a>, <a class='technorati-link' href='http://technorati.com/tag/inotifypropertychanged' rel='tag' target='_blank'>inotifypropertychanged</a>, <a class='technorati-link' href='http://technorati.com/tag/Silverlight' rel='tag' target='_blank'>Silverlight</a>, <a class='technorati-link' href='http://technorati.com/tag/WPF' rel='tag' target='_blank'>WPF</a></p>

<!-- end wp-tags-to-technorati -->
]]></content:encoded>
			<wfw:commentRss>http://www.grumpydev.com/2009/08/26/bindings-not-updating-in-wpf-silverlight-common-mistakes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
