tag:blogger.com,1999:blog-51393245312037682102009-11-24T11:17:13.788-08:00Michael Braude's Technical BlogNerdy tidbits from my life as a software engineerMichael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.comBlogger87125tag:blogger.com,1999:blog-5139324531203768210.post-88426444957953649052009-11-20T16:43:00.001-08:002009-11-20T16:43:01.666-08:00Sometimes, I Need a Reminder<p>Occasionally, when I get bogged down in something complicated, I start to feel as though the only way I can make something work is if I just plug through it in the most linear fashion possible.&#160; One of the hardest things to remember when writing code, I think, is that although programs are executed in a linear, functional, and procedural manner – you rarely want your code to be structured that way.&#160; This is the whole advantage of object orientated programming.&#160; But sometimes it’s tough to see the forest through the trees.&#160; It can feel as though a certain task can only be written in a procedural way, and this inevitably leads to monstrously monolithic horrors of methods - thousands of lines long and impossible to comprehend.&#160; And the funny thing is that it’s only after I realize it’s complexity that the light goes off in my head and reminds me that I need to factor something out.</p> <p>I suppose part of the problem is that when you’re banging something away, trying to get a complicated block of code to work, rarely are you thinking about proper design.&#160; And though I try, and am usually quite good at recognizing when to separate things, occasionally, I miss the boat.&#160; And then, also, it is usually only after the fact that I realize I can simplify things if I take an object orientated approach to solving it.&#160; Usually, at the time, it doesn’t occur to me that I can simplify anything because in my head, every step is being formed one after the other.</p> <p>So, I’m going to try and make a new pledge to myself.&#160; If a method I’m working on ever exceeds 250 lines of code, then it will prompt an automatic review.&#160; I imagine that only in a few scenarios does it ever make sense to have methods over 500, let alone a 1000 lines of code.&#160; Sure it happens, but I suspect that probably means you need to separate things out in a more OO manner.&#160; It’s just unfortunate that it doesn’t always occur to me as I’m coding, because it’s always more costly to make it so after the fact.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-8842644495795364905?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com3tag:blogger.com,1999:blog-5139324531203768210.post-67894382061458922882009-11-12T10:52:00.001-08:002009-11-12T10:53:09.700-08:00No Way Around It<p>I’ve been working on some code recently that does some pretty exciting things by cloning the IL of a method and executing it dynamically.&#160; The cloned method looks identical to the target method, save for a few small details in order to make it testable.&#160; Making this work with the DynamicMethod class is relatively trivial, because the constructor has a flag that allows you to skip visibility checks when the method gets jitted.&#160; If you want the dynamic method to access private members or classes of a class, then you have to set this flag to true or else you’ll get runtime errors due to visibility constraints.</p> <p>The problem is that there is no way to associate debugging information with DynamicMethods, which is a real bummer, because the whole point of this is to make testing code easier.&#160; If you can’t step through code that you’re testing, then you’re sort of back to square one.&#160; This is especially vexing because, since I’m cloning a method, I already have access to all the debug information from the target method and it’s trivial to copy it while I’m emitting the OpCodes.&#160; But since DynamicMethod is not debuggable, the only way to associate debug information with dynamically generated code is to use the standard DynamicMethodBuilder class / Reflection.Emit API, which <a href="http://blogs.msdn.com/jmstall/archive/2005/02/03/366429.aspx">does support emitting debug information</a>.&#160; The problem there, is that there is no way to have DynamicAssemblies skip visibility checks.&#160; </p> <p>So here’s the choice: use DynamicMethod and loose debuggability, or use MethodBuilder and loose visibility skipping.&#160; But there is no way to skip visibility checks <em>and</em> make dynamic code debuggable.&#160; Which is a real shame, because if there was, it would open the door to a lot of exciting possibilities.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-6789438206145892288?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-48475337145128283632009-11-05T13:31:00.001-08:002009-11-05T13:31:16.977-08:00ILGenerator vs DynamicILInfo<p>I have a situation where I’m trying to clone the IL of a method, except with a few dynamic changes.&#160; In order to do that, I need to be able to take any arbitrary MSIL stream, parse it, and convert specific statements into something different but more or less the same.&#160; This actually isn’t as hard as you may think, provided you have something that can iterate over the various instructions and parse them into a sequence of <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_members(VS.100).aspx">OpCodes</a>.&#160; No, the things that make this difficult are:</p> <ol> <li>The <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator(VS.100).aspx">ILGenerator</a> class does not expose a way to set byte code directly, which is something I need to do in this case.&#160; Otherwise I have a basically impossible job of reverse engineering an arbitrary stream and convert it into the right overload of the various Emit methods.&#160; This is just way too difficult.&#160; Imagine keeping track of labels and break statements?&#160; No thanks.&#160; It may be theoretically possible, but not easily. <br /></li> <li>The solution to this problem is to use <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.dynamicmethod(VS.100).aspx">DynamicMethod</a> and set the IL directly using the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.dynamicilinfo(VS.100).aspx">DynamicILInfo</a> class.&#160; This is a super low-level way of setting instructions dynamically, but it comes with one very large compromise, and that is that <a href="http://blogs.msdn.com/jmstall/archive/2006/11/14/lcg-feedback.aspx">you can’t associate debug symbols with DynamicMethods</a>.&#160; Since the method’s I’m generating are based off of almost identical source code, it would really be a shame if there were no ways to step through the generated code.&#160; Otherwise, debugging failures will be a nightmare.</li> </ol> <p>So I’m stuck in a hard place, trying to see if there are things coming in .NET 4 that might make this easier.&#160; So far I don’t see anything.&#160; If only I could combine the <a href="http://msdn.microsoft.com/en-us/library/9awh3x18(VS.100).aspx">SetBytes</a> method in <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.dynamicilinfo(VS.100).aspx">DynamicILInfo</a> with the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator.marksequencepoint(VS.100).aspx">MarkSequencePoint</a> on the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator(VS.100).aspx">ILGenerator</a>, I’d be much happier right now.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-4847533714512828363?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-50319506714455562672009-10-13T11:01:00.001-07:002009-10-13T11:01:27.784-07:00Introducing the “Scaffold” Generator<p>A while ago, I started a project that generated a library of objects that I called “Scaffolds”.&#160; The idea was to take any hierarchy, like this:</p> <p><a href="http://lh6.ggpht.com/_e966vsQhLfE/StTAcOndkZI/AAAAAAAAASU/nMpB4lHGcHI/s1600-h/Scaffold-1%5B4%5D.gif"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Scaffold-1" border="0" alt="Scaffold-1" src="http://lh3.ggpht.com/_e966vsQhLfE/StTAcXd5G3I/AAAAAAAAASY/VNR41N5INUY/Scaffold-1_thumb%5B2%5D.gif?imgmax=800" width="73" height="241" /></a> </p> <p>And generate an identical series of interfaces that mirrors this hierarchy, like this:</p> <p><a href="http://lh6.ggpht.com/_e966vsQhLfE/StTAclYDtoI/AAAAAAAAASc/fMJjlR34UvU/s1600-h/Scaffold-2%5B3%5D.gif"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Scaffold-2" border="0" alt="Scaffold-2" src="http://lh5.ggpht.com/_e966vsQhLfE/StTAdOUEmFI/AAAAAAAAASg/WmkeaesBl8U/Scaffold-2_thumb%5B1%5D.gif?imgmax=800" width="168" height="240" /></a>Now that you’ve got two matching hierarchies, you can generate a class that extends an object on one hierarchy and implements the matching interface on the other.&#160; The benefit of this is that this class can be referenced by either hierarchy, at run time.&#160; You can either deal with it via it’s base class, or by it’s generated abstraction.&#160; The resulting pattern I coined a scaffold:</p> <p><a href="http://lh3.ggpht.com/_e966vsQhLfE/StTAdU31b7I/AAAAAAAAASk/AWGlbyIfaJM/s1600-h/Scaffold-3%5B4%5D.gif"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Scaffold-3" border="0" alt="Scaffold-3" src="http://lh4.ggpht.com/_e966vsQhLfE/StTAdt-ZYBI/AAAAAAAAASo/3NFQ7ODqLoY/Scaffold-3_thumb%5B2%5D.gif?imgmax=800" width="368" height="241" /></a> </p> <p>The nice thing about using scaffolds is that they can be used in unit tests to test objects that are filled with non-virtual methods.&#160; For instance, here’s how you could use a ComboBoxScaffold in XAML:</p> <div> <pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">UserControl</span> <span class="attr">x:Class</span><span class="kwrd">=&quot;Examples.MainWindowControl&quot;</span> <br /> <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br /> <span class="attr">xmlns:s</span><span class="kwrd">=&quot;clr-namespace:System.Windows.Controls.Scaffolds;assembly=System.Windows.Controls.Scaffolds&quot;</span><br /> <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">Orientation</span><span class="kwrd">=&quot;Horizontal&quot;</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">s:ComboBoxScaffold</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;mComboBox&quot;</span><br /> <span class="attr">SelectedIndex</span><span class="kwrd">=&quot;0&quot;</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span>Item 1<span class="kwrd">&lt;/</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span>Item 2<span class="kwrd">&lt;/</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span>Item 3<span class="kwrd">&lt;/</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span>Item 4<span class="kwrd">&lt;/</span><span class="html">ComboBoxItem</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;/</span><span class="html">s:ComboBoxScaffold</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Click</span><span class="kwrd">=&quot;OnOKButtonClicked&quot;</span><span class="kwrd">&gt;</span>OK<span class="kwrd">&lt;/</span><span class="html">Button</span><span class="kwrd">&gt;</span><br /> <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">UserControl</span><span class="kwrd">&gt;</span></pre> </div> <p><span class="kwrd"></span></p> <p></p> <div>And now, in you’re code-behind, you can reference the ComboBoxScaffold by it’s abstraction – the IComboBox interface:</div> <div>&#160;</div> <div> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">using</span> System.Windows;<br /><span class="kwrd">using</span> System.Windows.Controls;<br /><span class="kwrd">using</span> System.Windows.Controls.Scaffolds;<br /><br /><span class="kwrd">namespace</span> Examples<br />{<br /> <span class="rem">/// &lt;summary&gt;</span><br /> <span class="rem">/// This contains the code for the MainWindowControl.</span><br /> <span class="rem">/// &lt;/summary&gt;</span><br /> <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> MainWindowControl : UserControl<br /> {<br /> <span class="rem">/// &lt;summary&gt;</span><br /> <span class="rem">/// Initializes the window.</span><br /> <span class="rem">/// &lt;/summary&gt;</span><br /> <span class="kwrd">public</span> MainWindowControl()<br /> {<br /> InitializeComponent();<br /> <span class="kwrd">this</span>.ComboBox = mComboBox;<br /> }<br /><br /> <span class="rem">/// &lt;summary&gt;</span><br /> <span class="rem">/// Gets / sets the combo box.</span><br /> <span class="rem">/// &lt;/summary&gt;</span><br /> <span class="kwrd">public</span> <span class="kwrd">virtual</span> IComboBox ComboBox<br /> {<br /> get;<br /> set;<br /> }<br /><br /> <span class="rem">/// &lt;summary&gt;</span><br /> <span class="rem">/// Called when the OK button is clicked.</span><br /> <span class="rem">/// &lt;/summary&gt;</span><br /> <span class="rem">/// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;</span><br /> <span class="rem">/// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span><br /> <span class="kwrd">private</span> <span class="kwrd">void</span> OnOKButtonClicked(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br /> {<br /> <span class="kwrd">this</span>.ComboBox.SelectedIndex++;<br /> }<br /><br /> }<br /><br />}<br /></pre> </div> <p></p> <div>Again, since the ComboBoxScaffold is-a ComboBox and is also an IComboBox, it can be used, interchangeably, in both hierarchies without any modifications.&#160; The very nice thing is that this allows us to unit test the MainWindowControl using mock API’s like Rhino, without any additional voodoo:</div> <div>&#160;</div> <div> <pre id="codeSnippet" class="csharpcode"><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Gets / sets the mock repository.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br /><span class="kwrd">public</span> Rhino.Mocks.MockRepository Mocks<br />{<br /> get;<br /> set;<br />}<br /><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">///A test for OnOKButtonClicked</span><br /><span class="rem">///&lt;/summary&gt;</span><br />[TestMethod()]<br /><span class="kwrd">public</span> <span class="kwrd">void</span> OnOKButtonClickedTest()<br />{<br /> MainWindowControl_Accessor target = <span class="kwrd">new</span> MainWindowControl_Accessor();<br /> <br /> IComboBox comboBox = <span class="kwrd">this</span>.Mocks.CreateMock&lt;IComboBox&gt;();<br /><br /> Expect.Call(comboBox.SelectedIndex).Return(1);<br /> comboBox.SelectedIndex = 2;<br /> <span class="kwrd">this</span>.Mocks.ReplayAll();<br /><br /> target.ComboBox = comboBox;<br /> <br /> target.OnOKButtonClicked(<span class="kwrd">null</span>, <span class="kwrd">null</span>);<br /> <span class="kwrd">this</span>.Mocks.VerifyAll();<br /><br />}<br /></pre> </div> <p></p> <div>I had everything all lined up to go ahead with this project, and then, for some reason, I got distracted by something else and never completed it.&#160; Now it’s almost done and I should have a working version ready in a few weeks or so.&#160; The code you need to generate to do this is actually fairly simple.&#160; The only drawback I can see to using scaffolds in your code is that you need to reference a relatively large library of pass-through classes in your code just so that it becomes testable.&#160; But I suppose, that’s a small price to pay for the ability to unit test API’s that are otherwise untestable.&#160; Don’t you think?</div> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-5031950671445556267?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com2tag:blogger.com,1999:blog-5139324531203768210.post-60164811772179233472009-09-08T13:13:00.001-07:002009-09-08T13:13:49.569-07:00Please Don’t Remove Order Validation!<p>Today, a coworker brought to my attention that the current plan for Rhino Mocks 4.0 is to remove the record / replay syntax in favor of the arrange / act / assert pattern.&#160; These are the plans for Rhino <a href="http://ayende.com/Blog/archive/2009/09/03/planning-for-rhino-mocks-4.0.aspx">v4.0, from Ayende Rahien’s blog</a>:</p> <blockquote> <li>Kill the dynamic, strict, partial and stub terminology. No one cares. It is a fake. </li> <li><strong>Remove the record / playback API. The AAA method is much simpler. </strong></li> <li>Simplify mocking options, aiming at moving as much as possible from expectation style to assert style. </li> <li>Keep as much of the current capabilities as we can. That means that if Rhino Mocks was able to support a scenario, it should still support it for the 4.0 version, hopefully in a simpler fashion.</li> </blockquote> <p>I too have become a big fan of stubs over the last year.&#160; They have the definite advantage of being far more accessible and understandable than mock recordings.&#160; They make unit tests easier to debug and to edit and maintain.&#160; I think they are a great leap forward.</p> <p>However:</p> <p>There are plenty of use cases where validating order is still critical.&#160; A stupid, make-believe example: I want to make sure that my unit test calls a web service before it sends the result in a database.&#160; If I can’t validate this order, then somebody could swap those two method calls and my test would still pass, even though it clearly isn’t working properly.&#160; The ability to ensure that a method on object A is invoked before a method on object B is invoked is critical.&#160; If you remove this, then an important unit testing tool will go away.&#160; Furthermore, it is also important to be able to define order-based behavior.&#160; For instance, saying that the first time a method is called, it should do this; the second time, it should do this, etc.&#160; It’s not enough to only differentiate this behavior based on method arguments: you need to be able to explicitly define behavior based on order.</p> <p>The rebellion against interaction-testing is understandable, and I’m not disagreeing with it – only advocating that the ability to do so stays.&#160; What I think people really want is to somehow combine the behavior or mocks with the behavior of stubs and somehow roll them into one unit testing object.&#160; But how could that work?&#160; </p> <p>I have no understanding of how Rhino works, but in my own personal framework, I designed mock recordings as state machines (a la regular expressions).&#160; This is because, at its heart, a mock object’s behavior is implicitly tied to order – and not just order on itself, but order in relation to other objects.&#160; Think of a recording block as a graph, where nodes are states and the links from state to state are method calls on on mock objects:</p> <p><a href="http://lh4.ggpht.com/_e966vsQhLfE/Sqa69uuLboI/AAAAAAAAASM/NUA7vVEXVwk/s1600-h/MockStateMachine%5B7%5D.gif"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="MockStateMachine" border="0" alt="MockStateMachine" src="http://lh4.ggpht.com/_e966vsQhLfE/Sqa6-ifTRrI/AAAAAAAAASQ/9aRAbfEEGwc/MockStateMachine_thumb%5B8%5D.gif?imgmax=800" width="572" height="404" /></a> </p> <p>This state machine is created on the fly within a recording block, and your tested code attempts to walk the graph from state 0 to the end at state3.&#160; Calls to validate the replay ensure that the state machine advanced all the way through the graph up to the last, final state (that way, if you comment out the target method, the test will fail).&#160; If you wrote the replay down on paper, it would look something like this:</p> <table border="1" cellspacing="0" cellpadding="2" width="400"><tbody> <tr> <td valign="top" width="133"> <p align="left">Step</p> </td> <td valign="top" width="133">Method</td> <td valign="top" width="133">State</td> </tr> <tr> <td valign="top" width="133">0</td> <td valign="top" width="133">-</td> <td valign="top" width="133">0</td> </tr> <tr> <td valign="top" width="133">1</td> <td valign="top" width="133">a.Foo()</td> <td valign="top" width="133">1</td> </tr> <tr> <td valign="top" width="133">2</td> <td valign="top" width="133">b.Bar()</td> <td valign="top" width="133">2</td> </tr> <tr> <td valign="top" width="133">3</td> <td valign="top" width="133">b.FooBar()</td> <td valign="top" width="133">2</td> </tr> <tr> <td valign="top" width="133">4</td> <td valign="top" width="133">a.fooBar()</td> <td valign="top" width="133">2</td> </tr> <tr> <td valign="top" width="133">5</td> <td valign="top" width="133">b.FooBar()</td> <td valign="top" width="133">2</td> </tr> <tr> <td valign="top" width="133">6</td> <td valign="top" width="133">b.Done()</td> <td valign="top" width="133"><u>3</u></td> </tr> </tbody></table> <p>Stubs, by contrast, don’t have this ordering built into them.&#160; And how could they without turning into Mocks?&#160; </p> <p>One idea that has been proposed is to let the act stage generate the above graph for you, and then have the assert stage optionally verify the graph.&#160; The reason this won’t practically work is that to do so, you would need to have your assert code walk the entire graph, which means you would end up having a block of code that looks identical to what we already are defining in our current recording block.&#160; Except that now, on top of defining behavior in the assert stage, we are <em>also</em> defining behavior in the arrange stage.&#160; Ack!&#160; Haven’t we just doubled our complexity without addressing the complaint of tightly coupling our test-code with our target code?&#160; I think the real thing we need to address are ways to make it easier to diagnose exceptions and keep recording blocks up to date.&#160; My <a href="http://www.michaelbraude.com/2009/03/mock-state-visualizer-to-rescue.html">mock state visualizer</a> is one attempt to help in this area, although it doesn’t completely solve the problem.</p> <p>I just want to remind everybody, that a mock can behave just like a stub.&#160; It all depends on how you record.&#160; Make an unordered recording and set the minimum number of calls to 0.&#160; There: you now, more or less, have a stub.</p> <p>This complaint appears to be the classic problem of, “You gave me the power to do something stupid.&#160; Now my code is a mess and it’s all your fault.”&#160; As the cheesy Spiderman saying goes, “with great power comes great responsibility.”&#160; It’s not GM’s fault that people die when they drive recklessly.&#160; Likewise, it’s not Rhino’s fault that some unit tests are overly complex.&#160; This is why we debate best practices and chide those who don’t abide by them.&#160; But taking the power away completely?&#160; That’s a drastic step which I do not support.&#160; </p> <p>So I hope Ayende decides to keep interaction testing alive as it currently is.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-6016481177217923347?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com2tag:blogger.com,1999:blog-5139324531203768210.post-20281218991333733282009-09-03T17:42:00.001-07:002009-09-03T17:42:52.719-07:00Um, That Seems Hokey (Restarting WPF Applications)<p>I’m sure there’s a better way to do restart a WPF application manually after it self-updates using click-once deployment.&#160; But as of right now, I can’t seem to find one.&#160; Chalk this hackishness up to a lack of a Restart() method on the <a href="http://msdn.microsoft.com/en-us/library/system.windows.application.aspx">System.Application</a> class:</p> <div id="codeSnippetWrapper"> <pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Invoked when the updating is completed.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br /><span class="rem">/// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;</span><br /><span class="rem">/// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span><br /><span class="kwrd">private</span> <span class="kwrd">void</span> OnUpdatingCompleted(<span class="kwrd">object</span> sender, AsyncCompletedEventArgs e)<br />{<br /> MessageBox.Show(<span class="kwrd">this</span>,<br /> <span class="str">&quot;The application has been updated and will now restart.&quot;</span>,<br /> <span class="str">&quot;Update Complete&quot;</span>,<br /> MessageBoxButton.OK,<br /> MessageBoxImage.Information);</pre> <pre class="csharpcode"><br /><br /> <span class="rem">// We have to write a silly temp file to restart the application. Icky.</span><br /> <span class="kwrd">string</span> batchFile = System.IO.Path.GetTempFileName();<br /> batchFile = System.IO.Path.ChangeExtension(batchFile, <span class="str">&quot;bat&quot;</span>);</pre> <pre class="csharpcode"><br /><br /> <span class="kwrd">using</span> (StreamWriter writer = <span class="kwrd">new</span> StreamWriter(File.Create(batchFile)))<br /> {<br /> <span class="kwrd">string</span> location = Assembly.GetExecutingAssembly().Location;<br /> writer.WriteLine(<span class="str">&quot;start &quot;</span> + location);<br /> }</pre> <pre class="csharpcode"><br /><br /> Application.Current.Exit += (o, a) =&gt;<br /> {<br /> <span class="kwrd">using</span> (Process p = <span class="kwrd">new</span> Process())<br /> {<br /> p.StartInfo.FileName = batchFile;<br /> p.Start();<br /> }<br /> };</pre> <pre class="csharpcode"><br /><br /> Application.Current.Shutdown();</pre> <pre class="csharpcode"><br />}</pre> <p></p> Wow.&#160; Have you ever seen something so messy before?&#160; I would like a good explanation for why I need to write a batch file to the temp directory so that I can restart an application manually after it updates itself via click-once.&#160; Why not implement the Restart() method in the System.Application class?</div> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-2028121899133373328?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com4tag:blogger.com,1999:blog-5139324531203768210.post-15174842153534081012009-08-28T15:51:00.001-07:002009-08-28T15:53:25.571-07:00Determining Visibility To Internals<p>How do you determine, programmatically, whether Assembly A has visibility to objects and methods in Assembly B that are labeled internal?&#160; The answer is: not easily.&#160; It would be nice if there was a quick and easy way to check this, but as far as I can tell, there is none.&#160; Which means that the best way to do this is to just scan the target assembly for any InternalsVisibleTo attributes and match them up to the assembly you’re checking against:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Checks to see if the source assembly has permission to view the internals of the target assembly.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br /><span class="rem">/// &lt;param name=&quot;source&quot;&gt;The assembly that wants access&lt;/param&gt;</span><br /><span class="rem">/// &lt;param name=&quot;target&quot;&gt;The assembly whose internals the source wants to access&lt;/param&gt;</span><br /><span class="rem">/// &lt;returns&gt;True if the source assembly has access to the target; otherwise false&lt;/returns&gt;</span><br /><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> CanSeeInternalsOf(Assembly source, Assembly target)<br />{<br /> <span class="kwrd">object</span>[] attributes = target.GetCustomAttributes(<span class="kwrd">typeof</span>(InternalsVisibleToAttribute), <span class="kwrd">true</span>);<br /> <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; attributes.Length; i++)<br /> {<br /> InternalsVisibleToAttribute internalsAttribute = attributes[i] <span class="kwrd">as</span> InternalsVisibleToAttribute;<br /> <span class="kwrd">if</span> (internalsAttribute != <span class="kwrd">null</span>)<br /> {<br /> <span class="kwrd">if</span> (internalsAttribute.AssemblyName.StartsWith(source.GetName().Name))<br /> <span class="kwrd">return</span> <span class="kwrd">true</span>;<br /> }<br /> }<br /> <span class="kwrd">return</span> <span class="kwrd">false</span>;<br />}</pre> </div> <p>The reason you need to use the StartsWith method is because the AssemblyName could have a very long, stupendously unreadable public key associated with it – which you could [not easily] include in your comparison.&#160; So you’ll need to ignore it in order to make the comparison.&#160; Theoretically, this could fail if you ever tried to compare assemblies that had the same name but different keys.&#160; Oh well; such is life.&#160; At least there’s a way to do it, even if it’s far more convoluted than it should be.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-1517484215353408101?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-11018494673028846602009-08-26T17:31:00.001-07:002009-08-26T17:35:11.202-07:00Why Not Anonymous Add / Remove Methods?<p>In .NET 3.0 and above, the compiler frees you from the monotony of having to specify the actual member variables that you are exposing via properties by allowing the compiler to generate them for you.&#160; So rather than cluttering your code with stuff that looks like this:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">int</span> mMyInteger;<br /><br /><span class="kwrd">public</span> <span class="kwrd">int</span> MyInteger<br />{<br /> get<br /> {<br /> <span class="kwrd">return</span> mMyInteger;<br /> }<br /> set<br /> {<br /> mMyInteger = <span class="kwrd">value</span>;<br /> }<br />}</pre> <p>You can have the compiler generate this for you by making the get and set methods anonymous:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">int</span> MyInteger<br />{<br /> get;<br /> set;<br />}</pre> </div> </div> <div id="codeSnippetWrapper"> <p>But today I discovered that the same privilege is not afforded to the add / remove methods on events.&#160; This, for instance, is not legal C#:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">event</span> SomeHandler OnSomeEvent<br />{<br /> add;<br /> remove;<br />}</pre> </div> </div> <p>The code above will fail with the error, “An add or remove accessor must have a body.”&#160; If you want to hook into the add and remove methods, you need to specifically add and remove the delegate just like you used to have to do with simple properties:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">event</span> SomeHandler mOnSomeEvent;<br /><br /><span class="kwrd">public</span> <span class="kwrd">event</span> SomeHandler OnSomeEvent<br />{<br /> add<br /> {<br /> mOnSomeEvent += <span class="kwrd">value</span>;<br /> }<br /> remove<br /> {<br /> mOnSomeEvent -= <span class="kwrd">value</span>;<br /> }<br />}</pre> <p>This is unfortunate.&#160; You’re probably wondering, why would you want to make them anonymous?&#160; If you did, why not just stick with the default syntax and specify a public event?&#160; IE,</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">event</span> SomeHandler OnSomeEvent;</pre> <p>is essentially the same thing, but even more shorthanded.&#160; While I admit that this is a bit of a special case, the reason this came up today is because I was trying to figure out how to set a mock expectation on the add method of an event and realized that the only real way to do this was to expose virtual add and remove methods that the framework could override and set expectations on:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">event</span> SomeHandler mOnSomeEvent;<br /><br /><span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">event</span> SomeHandler OnSomeEvent<br />{<br /> add<br /> {<br /> mOnSomeEvent += <span class="kwrd">value</span>;<br /> }<br /> remove<br /> {<br /> mOnSomeEvent -= <span class="kwrd">value</span>;<br /> }<br />}</pre> <p>It would be much more convenient if I could make the add / remove methods anonymous as I can with properties.&#160; Is there any harm in allowing the compiler to generate this for you?&#160; Or is this just an oversight by the language and compiler folks?</p> </div> </div> </div> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-1101849467302884660?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com1tag:blogger.com,1999:blog-5139324531203768210.post-66550036606407689802009-08-19T13:40:00.001-07:002009-08-21T07:59:15.196-07:00On The Netbook Craze<p>All this talk about netbooks has me a bit perplexed.&#160; What is a netbook?&#160; From what I can tell, it’s a super slim, lightweight notebook that’s optimized for portability, price, and battery life.</p> <p>But then we then go off into this whole sub-discussion about what sort of operating system a netbook should run on and what it’s primary purpose is, and this discussion makes no real sense to me.&#160; The idea that a netbook is only useful for surfing the Internet is based on the theory that because it’s super-cheap, it is incapable of doing anything else.&#160; This might be true today, but it clearly won’t be true tomorrow as hardware continues to get more powerful and less expensive – as it always has.&#160; And this makes the whole idea of an Internet-only notebook silly to me.&#160; Why not just call it a really cheap, low-end laptop?</p> <p>The earliest netbooks might have had 512MB of RAM and were incapable of running Vista.&#160; But obviously, within a year or two (if it’s not already), 2GB of RAM will be as cheap or cheaper than 512MB is today (or else the marginal difference will be so small that it won’t matter).&#160; So whatever netbook you can by today for $300.00, tomorrow you will be able to buy a far more powerful notebook for the same price – if not cheaper.&#160; And it will be absolutely fully-capable of running just about anything you want it to.&#160; So why pretend that the purpose of these machines is to limit ourselves to just browsing the Internet?</p> <p>So I fail to see how this is any more of a threat to Windows than the Internet already is.&#160; It may be a threat to Microsoft’s margins, but really nothing else.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-6655003660640768980?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com8tag:blogger.com,1999:blog-5139324531203768210.post-22839385218309107622009-08-19T11:10:00.001-07:002009-08-19T11:26:51.777-07:00Backported From MSDN<p>On the heels of the backlash from my <a href="http://michaelbraude.blogspot.com/2009/05/why-ill-never-be-web-guy.html">web-guy rant</a> and <a href="http://www.codinghorror.com/blog/archives/001296.html">Mr. Atwoods tirade against me</a>, I decided to move my blog back to blogger from MSDN.&#160; Maybe this was a knee-jerk reaction to a bout of criticisms that I haven’t yet experienced on the Internet, but I felt that it was appropriate for me to try, as much as possible to separate myself and my opinions from my employer.&#160; It was disheartening to see people associate my rants with those of Microsoft as a whole; my whacky opinions do not pervade throughout the entire company.</p> <p>I understand that what whatever I write or say, I will always be representing Microsoft.&#160; But to me, the veil of blogging ‘under’ Microsoft’s blog-hosting service associates my opinions with those of my coworkers in a way that I’m not really comfortable.&#160; Also, I want to feel free to be critical of Microsoft and I felt somehow restricted when I was writing on MSDN.&#160; This is quite a struggle for me, actually.&#160; As thrilling as it is to work here, there are plenty of things about our products, services, and corporate behavior that infuriate me.&#160; Should I stand up and bite the hand that feeds me?&#160; I have been struggling with that question ever since I started here, but I want to at least feel more freedom to say what I want.</p> <p>Lastly, call me vain, but I want to keep using my domain name, and I was unable to port that to MSDN.&#160; Bummer.&#160; That would have been nice.&#160; Not to mention that there’s nearly three-years worth of blogging history here that I would hate to leave behind.</p> <p>Anyways, there are 6 posts from July that I ported over this morning.&#160; It’s unfortunate that I can’t port the comments, too.&#160; But you can go to the <a href="http://blogs.msdn.com/michaelbraude/archive/2009/07.aspx">original site and read those</a> if you want.&#160; I won’t delete them.</p> <p>I’ve considered cross-posting, but I hate the idea of having the same post in multiple places.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-2283938521830910762?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-48283032948151551732009-08-17T12:59:00.001-07:002009-08-19T11:14:44.382-07:00Re: All Programming is Web Programming<p>Jeff Atwood’s <a href="http://www.codinghorror.com/blog/archives/001296.html">tirade against me</a> is at least partially justified.&#160; I knew that my <a href="http://michaelbraude.blogspot.com/2009/05/why-ill-never-be-web-guy.html">rant against web-development</a> was inflammatory when I posted it.&#160; But in his diatribe, he omits a few important details from my post and then makes the same sort of sweeping generalizations that he’s criticizing me for making.</p> <p>First, while he takes a lengthily quote from my article, he happily omits this line where I acknowledge that, obviously, there are smart people who develop web pages:</p> <blockquote> <p>OK, so that’s not an entirely fair accusation to make.&#160; Of course there are smart people who like to work on the web, and who find challenging things about it.</p> </blockquote> <p>The premise for my rant is that this is not a challenging medium <em>for me</em>.&#160; I’m happy that other people find this environment challenging.&#160; To me it’s tedious and frustrating.&#160; Call me old-fashioned and out-dated, but I much prefer to develop in my full-featured desktop environment – the one that</p> <blockquote> <p>Computer Science [has] spent the last forty years making … as powerful as possible.<a href="http://www.codinghorror.com/blog/archives/000913.html">[1]</a></p> </blockquote> <p>Is it so bad for me to lament this movement backwards towards simpler technologies?&#160; Forty years worth of research and development have evolved to create an environment where we get to focus on things that matter (such as, what is the best way to architect a program so that it accomplishes our goals) and less on things that don’t (such as, how can I get this to work in a webpage).&#160; For me, this is a much more challenging problem to solve.</p> <p>[Note that by the term “web development”, I am specifically referring to the presentation layer of a webpage – not the back-end services that do all sorts of complex stuff.&#160; That’s not web-development – that’s just normal server-side development, and it encompasses all platforms and presentation layers, so it has nothing to do with the web, specifically]</p> <p>Next, Jeff goes on to rant about why the movement to the web makes perfect business sense (which I never disagreed with), and continues by saying that he does web-dev because it allows him to write software that gets used (which is another reason that I work for Microsoft).&#160; I understand why the world is moving in this direction; I just wish they were using more elegant technologies to do it.</p> <p>But my primary complaint is more due to the fact that the web-world is filled with terrible software engineers.&#160; I know that’s a dangerous accusation to make, but look: I taught myself DHTML when I was 15 with a used book that my father gave me – and I was quite good at it.&#160; We all know this stuff is easier than C++/C#/Java development – as politically incorrect as that may be to say – because it requires far less training to be effective at it and because there is no need to understand the underlying technologies and principles that they are built on.&#160; That doesn’t mean there aren’t brilliant people who work in this space, or that there aren’t amazing things being done on the web, or that all of the people who work with these technologies are dumb.&#160; But if Jeff can make laws, so can I:</p> <blockquote> <p>Braude’s Law: The easier it is to learn a given technology, the larger the percentage of bad engineers who will work with it.</p> </blockquote> <p>Can we really dispute this?&#160; Isn’t it self-evident?&#160; Yes, there are exceptions; but clearly, it takes more training and understanding to be a C++ guru than a DHTML guru.&#160; And because I want to work with people who can challenge me and who I can learn from, I choose to work with technologies where, crass as it may be to say, the bar is higher.</p> <p>But Jeff acknowledges that this is true:</p> <blockquote> <p>Web programming is far from perfect. It's <b>downright kludgy</b>. It's true that any J. Random Coder can plop out a terrible web application, and 99% of web applications are absolute crap. But this also means the truly <i>brilliant</i> programmers are now getting their code in front of hundreds, thousands, maybe even millions of users that they would have had absolutely no hope of reaching pre-web. There's nothing sadder, for my money, than code that dies unknown and unloved. Recasting software into web applications empowers programmers to get their software in front of <i>someone</i>, somewhere. Even if it sucks.</p> </blockquote> <p>I am not willing to sacrifice the quality of my development environment or the intelligence of my coworkers just so that I can get my code in front of people.&#160; He may be happiest writing programs that get used; but I am happiest writing elegant solutions to difficult problems with intelligent people.&#160; And that’s why, so long as the web is built on DHTML, I will never be a web-guy.&#160; It’s also why I work for Microsoft: here, I get to write applications using sophisticated technologies (many of which are invented here) to develop quality software that also gets in front of millions of people.</p> <p>Lots of people have pointed out that much of the DHTML stuff we see on the web these days is in fact auto-generated using more sophisticated technologies.&#160; These I have less of a problem working with.&#160; But what does it say about the quality of a development environment that we have to go out of our way to hide it from us?&#160; Ultimately, everything is still built on technologies that, as Jeff admits, suck.</p> <p>Lastly, I disagree with Jeff’s bad news:</p> <blockquote> <p>I hate to have to be the one to break the bad news to Michael, but for an increasingly large percentage of users, <a href="http://www.codinghorror.com/blog/archives/000883.html">the desktop application is already dead</a>. Most desktop applications typical users need have been replaced by web applications for years now. And more are replaced every day, as web browsers evolve to become more robust, more capable, more powerful. </p> <p>You <i>hope</i> everything doesn't &quot;move to the web&quot;? Wake the hell up! <b>It's already happened!</b></p> </blockquote> <p>Sure, lots of traditional desktop applications have moved to the web.&#160; But I’ve got some bad news for Jeff: not all programming is web programming, and as much as he may wish it to be true, it clearly hasn’t happened already.</p> <p>Want an obvious example?&#160; How about iTunes?&#160; Here’s a desktop application that hundreds of millions of people are using, so it’s clearly not a niche.&#160; Can we replace it with a web-app?&#160; Theoretically we probably could (we could also write it in punch cards or re-write it in assembly).&#160; But to do that, we would need to not only replicate the iTunes application in a web browser using JavaScript, we would also need to provide a platform-agnostic way for this web-app to talk to an iPod via a web browser.&#160; Perhaps this is possible, but let’s ask ourselves a question: is there any tangible advantage of going down this path?&#160; Are we really gaining anything, or are we just showing off how good we are at hacking a square peg into a round hole?</p> <p>And we can say the same thing about just about every prominent desktop application that, again, theoretically could be written in JavaScript.&#160; Do we really want a web-based version of Photoshop?&#160; Would we honestly prefer to develop applications in a in a web browser instead of Visual Studio or Eclipse?&#160; Would it please you more to design a PowerPoint presentation in the comfy-confines of Firefox?&#160; Why are we so intent on short-changing our user experience for the sake of cross-platform convenience?&#160; What, so that we don’t need Windows any more – is that really what all of this is about?</p> <p>But Jeff acknowledges as much when he writes:</p> <blockquote> <p>Writing Photoshop, Word, or Excel in JavaScript makes zero engineering sense, but it’s inevitable.</p> </blockquote> <p>This may be one thing that we agree on, but it doesn’t make me any happier.&#160; As much as I want everybody to use the products from the company that I work for, I am more interested in ensuring that our user-experience is as fantastic as it can possibly be.&#160; So it saddens me to watch us all happily trade down just so that we can get away from Windows.&#160; Truthfully, I chalk this gleeful movement up to my employer’s inability to continue creating exciting products and our lack of an app-store for Windows.&#160; But I’ve opined about that <a href="http://michaelbraude.blogspot.com/2009/06/random-weekend-thoughts.html">somewhere else</a>.</p> <p>While the web-movement is obviously here to stay and accelerate, I am not convinced that all programming will be web programming.&#160; A large number of things will have <a href="http://blogs.msdn.com/michaelbraude/archive/2009/07/15/why-the-web-will-always-be-second-best.aspx">to change before that can happen</a>.&#160; And if it does come true that all programming becomes this DHTML mess that we find ourselves in right now, then I will gladly change professions – or at least say hello to middle-management.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-4828303294815155173?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com59tag:blogger.com,1999:blog-5139324531203768210.post-506352354909159422009-07-27T10:47:00.000-07:002009-08-19T10:47:30.179-07:00The Importance Of Code Organization<p>If there is one thing I dislike about C#, it’s that it allows you to place definition statements where ever you want to.&#160; While there is technically a similar freedom in C++, the nature of header files and visibility blocks encourages people to group, say, member variables and public methods together.&#160; This encouragement is lost in C# because you have the freedom to scatter your member variables throughout your code files in any manner you want.</p> <p>To me, this freedom promotes some bad habits which make it difficult to understand and navigate through a large program.&#160; The reason is that if you scatter your member variables, properties, and methods around your source code in a random manner, it becomes difficult to figure out where they are.&#160; The result is a large amount of wasted time as people hunt through your source code to find what they are looking for.</p> <p>So I have one rule for anything I ever write: given the given fully qualified name of a class and it’s members, it should be <em>immediately obvious to anybody</em> where in your source code that member, property or method is defined.&#160; Nobody should need to search for it.&#160; Just from the namespace, they should be able to deduce – within a handful of clicks – where something is defined in your file structure.</p> <p>For instance, say I have an int whose fully qualified namespace is:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">int</span> My.Program.DataTypes.SomeData.mID</pre> </div> <p>If my solution contains two projects called My.Program and My.Program.DataTypes, I should expect to see the definition for mID in the My.Program.DataTypes project in a file called SomeData.cs.&#160; Furthermore, I should expect to see the mID member variable defined in a particular section of SomeData.cs so that there is no need to hunt through the file to find it. </p> <p>Any given class file can contain large numbers of member variables, properties, methods, event handlers, interface implementations, etc.&#160; How would a random person know where in a given file a member variable is defined if you chose to scatter these definitions randomly throughout the source file?&#160; In order to make it immediately obvious where to go to find a given member variable, I always group them together and – optionally – surround them with #region elements.&#160; This way, if you open SomeData.cs and want to find the ID property, you can quickly browse to it by expanding the “Public Properties” region and scrolling down until you find it.&#160; No search box necessary – it is obvious where the property is defined.</p> <p>Why is this important?&#160; Two reasons.&#160; First, it makes your code more readable because things are laid out in an order that makes sense.&#160; And second, because it saves a large amount of time and overhead.&#160; The cost of searching for something in a large program is high enough that it should be avoided.&#160; You should simply not have to search your code in order to discover where things are defined.</p> <p>This is also my principle complaint about public inner classes.&#160; The problem with inner classes is that it is not clear where they are just from looking at their full-qualified name.&#160; For instance, I would expect:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode">var myObject = <span class="kwrd">new</span> My.Program.ObjectModel.SomeObject</pre> to reside in a project called My.Program, within a folder called ObjectModel, in a file called SomeObject.cs.&#160; But if SomeObject is an inner class of ObjectModel, it is not clear from looking at the name of the class where it’s code is defined because it’s not obvious whether ObjectModel is a class or a namespace.&#160; When things get super inner-nested, this entanglement becomes even more confusing.</div> <div>&#160;</div> <div>(Inner classes also prevent you from leveraging using statements to reduce long-winded class names, which in turn makes your code less readable because it becomes cluttered with lots of unnecessary scoping)</div> <div>&#160;</div> <div>It is easy to write code in an organized manner.&#160; Simply put new source files in locations that correspond with their namespace and define your members, properties and methods in the same sections of your code files.&#160; That’s not too hard, is it?&#160; It is much harder to take a program that was not written this way and separate things out into locations that are logical.&#160; And it is even harder to understand a project where everything is defined in scattered, unorganized source files.&#160; </div> <div>&#160;</div> <div>So my advice is to do it right the first time.&#160; Avoid future headaches from the start, make it easy for other engineers to collaborate with you, and reduce the overhead required to alter your work.&#160; It’s a quick investment that continues paying dividends long after you’ve moved onto something else.</div> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-50635235490915942?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com2tag:blogger.com,1999:blog-5139324531203768210.post-76959113295266699462009-07-15T10:43:00.000-07:002009-08-19T10:46:10.751-07:00Why The Web Will Always Be Second Best<p>For all of the euphoria surrounding the exciting things coming out on the Internet these days, I think it’s important to remind ourselves of the limitations that web technologies naturally imposes on us.</p> <p>All executed code needs to be compiled into machine code before it can be executed on the local machine, and the process looks like this:</p> <p><a href="http://lh5.ggpht.com/_e966vsQhLfE/Sow6YAN8QBI/AAAAAAAAASE/0ec--gnymyk/s1600-h/Compiler13.gif"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Compiler" border="0" alt="Compiler" src="http://lh3.ggpht.com/_e966vsQhLfE/Sow6YdHpbaI/AAAAAAAAASI/hCsFZ4cTiZo/Compiler_thumb21.gif?imgmax=800" width="351" height="601" /></a></p> <p>Now I don’t profess to be an expert on compilers, but I know enough to draw this conclusion on JavaScript: it will never be as fast as native or intermediate code.&#160; And the reason why is because in order to execute a super-heavy JavaScript library, everything you see above needs to happen as soon as you open a webpage.</p> <p>This may not seem like a big deal, but remember that text parsing is actually incredibly slow.&#160; For the uninitiated, the process of converting source code into a recognizable stream of tokens (IE keywords such as “int” and “class”) is done via <a href="http://www.bing.com/search?q=regular+expressions&amp;form=QBRE&amp;qs=AS">regular expressions</a>.&#160; Regular expression matching is very time consuming, and there is quite simply no way around this.&#160; Perhaps the algorithm can be sped up to some degree, but its complexity cannot be reduced: for a given text file of N characters, each of them needs to be scanned from start to finish – and this takes O(N) time.</p> <p>The parser then takes this stream of tokens and converts it into a syntax tree, which can then be converted into native code (or evaluated, in the case of JavaScript).&#160; If we imagine that an entire program can be converted into one big tree of some unknown height, we can conclude that the complexity of parsing this tree and executing it is equal to the it’s height.&#160; Or, roughly O(log(N)), for some base log that I can only estimate.</p> <p>I’m just guesstimating here, but I imagine that the total complexity of compiling an application is about O(N Log(N)), which makes it roughly equal with the complexity of <a href="http://www.bing.com/search?q=quick+sort&amp;form=QBLH&amp;qs=n">quick sort</a>.&#160; So in addition to downloading an entire JavaScript application – in its verbose, text-based, precompiled form – a JavaScript application needs to go through the overhead above.&#160; For small applications, this additional overhead is just about negligible.&#160; But as applications grow larger and larger, it will become more and more pronounced.&#160; In the end, it will end up being the largest barrier that prevents JavaScript from becoming the language of choice for highly-featured web-based applications.</p> <p>Keep in mind that the largest JavaScript applications on the Internet are a few megabytes or so in size.&#160; Loading and running these applications right now, while fast, still takes noticeable time (look at the progress bar on GMail, for instance).&#160; But if you consider that most large commercial applications consist of many tens of millions of lines of code which take up many gigabytes of space and take many hours to compile, you can start to see the natural limitations of JavaScript.&#160; A JavaScript application of that size, while perhaps theoretically possible, would take so long to load that it wouldn’t be usable – no matter what tricks you use to speed it up.</p> <p>You may think that this is a limitation that will go away over time as new technologies and&#160;&#160; techniques arrive that speed things up.&#160; But years from now, future applications will be even larger than they are today.&#160; So even if JavaScript applications can eventually catch up with today’s desktop applications, the bar will rise, our standards will increase, and today’s applications will look puny by tomorrow’s standards.&#160; Of course, there are technologies emerging that speed JavaScript up significantly, including many within Microsoft.&#160; These are exciting and will no doubt increase the limit of what can be done in a browser.&#160; But ultimately, no advancement will ever bring the two environments on par with each other, because the complexity of compiling or interpreting on the fly is a constant that cannot be reduced.</p> <p>I think it’s time we recognize JavaScript for what it is: a <em>scripting</em> language that is being used for purposes beyond what it was conceived for.&#160; If we really want rich applications to be delivered over the internet and hosted in a web browser, we will need to think of a better technology for doing so.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-7695911329526669946?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com5tag:blogger.com,1999:blog-5139324531203768210.post-71407596613025545392009-07-13T10:41:00.000-07:002009-08-19T10:43:21.439-07:00WCF Duplex Bindings With Silverlight<p>I have had the hardest time getting my self-hosted WCF service to play nicely with Silverlight.&#160; I thought this was supposed to be simple, but it turns out that exposing a self-hosted, WCF service with a callback contract to a Silverlight application is just about impossible.&#160; Here are the five hurdles you have to overcome to get this to work:</p> <ol> <li>First, you have to explicitly give your <a href="http://blogs.msdn.com/anirbanc/archive/2008/05/14/wcf-error-http-could-not-register-url-http-8000-your-process-does-not-have-access-rights-to-this-namespace.aspx" mce_href="http://blogs.msdn.com/anirbanc/archive/2008/05/14/wcf-error-http-could-not-register-url-http-8000-your-process-does-not-have-access-rights-to-this-namespace.aspx">service permission</a> to open an endpoint on localhost at a specific URL.&#160; I’m sure this can be automated somehow, but probably not easily. </li> <li>You have to host a <a href="http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx">clientaccesspolicy.xml</a> file on the service in order to give the Silverlight runtime permission to call your service.&#160; This involves writing another WCF service just to <a href="http://www.orbifold.net/default/?p=1917" mce_href="http://www.orbifold.net/default/?p=1917">return basic documents via HTTP</a>.&#160; It’s not too tough, but very annoying. </li> <li>Silverlight does not support the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx">WSDualHttpBinding</a> binding.&#160; To get around this, the server needs to expose itself via a custom endpoint that is configured to use a PollingDuplexElement object.&#160;&#160; How you would ever figure this out without the help of <a href="http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx">this MSDN article</a>, I have no idea. </li> <li>Next, the Silverlight application needs to be configured with another custom binding that can communicate with this strange, bastardized endpoint that you have exposed on the server.&#160; Svcutil.exe does not pick this up for you: you’ve got to define this endpoint manually.&#160; Another <a href="http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx">MSDN article explains this nastiness</a>.&#160; Good luck finding this out by yourself. </li> <li>Whatever your <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx">ServiceContract</a> you had before you decided to add a Silverlight client will now need to change to send and receive using <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx">Message</a> objects.&#160; For me, this was a deal-breaker.&#160; All of your nice, strongly-typed <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx">DataContract</a>’s go away and get replaced with generic SOAP messages.&#160; Terrible.&#160; And all of your other clients now need to be updated to deal with these objects instead of the strongly-typed data structures that make WCF so powerful to use in the first place. </li> </ol> <p>All of these hurdles have caused me to put off the Silverlight client until further notice.&#160; The only way I can think of writing this is to do a very nasty double-hop scenario.&#160; And I really hate that idea.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-7140759661302554539?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-85808951501802215282009-07-08T10:40:00.000-07:002009-08-19T10:41:34.750-07:00Calling Self Hosted WCF Services from Silverlight<p>I have an application that self-hosts a WCF service.&#160; Now I want to add an HTTP endpoint to that application and have a Silverlight application call my service.&#160; Sounds easy.</p> <p>Except that it’s not, because the Silverlight app is trying to do a cross-domain web service call (since the endpoint is self-hosted), and for that to work, the endpoint needs to return a file called clientaccesspolicy.xml when the silverlight app asks for it.&#160; But since my application isn’t running in IIS (and I don’t want it to), returning this file when that HTTP request comes in is not a trivial thing to do.&#160; In fact, I don’t think it can be done.&#160; A self-hosted WCF service is not a web server – just an endpoint.</p> <p>So I’m a bit stuck, and a bit more perplexed.&#160; There must be a way to call a self-hosted WCF service from a Silverlight application, don’t you think?&#160; Or maybe not, which would be very frustrating, because then I’d either have to do it in JavaScript or I’d need to do some super-nasty webservice-that-calls-a-WCF-service architecture.&#160; And thinking about that just makes me cringe.&#160; But if it’s what I have to do, then I guess that’s what I’ll do.</p> <p>I don’t like this cross-domain restriction.&#160; I’m sure there’s a good reason behind it, but it seems to create more problems than it solves.</p> <p>UPDATE: There is, actually, a way to do this – though it’s not as intuitive as you might think.&#160; Check out the solution <a href="http://www.orbifold.net/default/?p=1917" mce_href="http://www.orbifold.net/default/?p=1917">here</a>.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-8580895150180221528?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com2tag:blogger.com,1999:blog-5139324531203768210.post-72928791064413439712009-07-08T10:37:00.000-07:002009-08-19T10:39:36.658-07:00The Beauty of Data-Driven Applications<p>A common problem I run into when writing applications is this:</p> <p>I have a situation where a series of tasks need to be assembled and arranged in a way that does something complicated.&#160; Each individual section may be simple, but the process as a whole is complicated.&#160; The pieces of this process need to be arranged dynamically, and I want the ability to update them and slot new pieces in without disrupting the system as a whole.&#160; What’s the best way to design such a system?</p> <p>Of course, no matter what, you want something with lots of abstractions – ways that disconnected pieces can plug into each other without really knowing who their neighbors are.&#160; That much is a given.&#160; But where do you <em>define</em> the process as a whole?&#160; In other words, where do you physically say, “For the process that I call ‘A’, first do Task1,&#160; then do Task2, then do Task3”, etc.?</p> <p>Perhaps the easiest and most obvious way to do this would be to use a simple object hierarchy.&#160; Something like this:</p> <p><a href="http://lh4.ggpht.com/_e966vsQhLfE/Sow40AvHOGI/AAAAAAAAAR8/hMubsBj9A3Q/s1600-h/DataDriven6.gif"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="DataDriven" border="0" alt="DataDriven" src="http://lh3.ggpht.com/_e966vsQhLfE/Sow416QrHzI/AAAAAAAAASA/cN3AsXqIpAw/DataDriven_thumb9.gif?imgmax=800" width="444" height="480" /></a> Now, you’re library of Task objects will grow whenever you need to add some new small block of functionality.&#160; And your library of Process objects will grow whenever you need to define a new process.&#160; An individual Process object may be very stupid, and could simply look like this:</p> <div> <pre id="codeSnippet" class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> ProcessA : BaseProcess<br />{<br /> <span class="kwrd">public</span> ProcessA()<br /> {<br /> <span class="kwrd">this</span>.Tasks = <span class="kwrd">new</span> BaseTask[]<br /> {<br /> <span class="kwrd">new</span> TaskA(),<br /> <span class="kwrd">new</span> TaskB(),<br /> <span class="kwrd">new</span> TaskC(),<br /> ...<br /> };<br /> }<br />}</pre> </div> <div>All of the business logic on how to execute a process can be contained inside the generic BaseProcess object, so the only thing that the subclasses need to do is define the array of tasks that get executed and what their order is.&#160; In other words, the only purpose of the subclasses is to define the data that the parent class needs in order to execute.</div> <div>&#160;</div> <div>Things get more tricky, however, when more complicated connections needs to be defined.&#160; Just defining a sequence of tasks may not be enough.&#160; Maybe we also need to define what output from what task goes into the input of another task.&#160; Where do we define that logic?&#160; How do we represent it?&#160; Potentially, we could just shove it into our current model and everything will be fine.&#160; But we could soon find ourselves writing a lot of code that just glues these things together.&#160; And that makes me wonder: how much decoupling have we really achieved by separating these tasks into separate procedures instead of just strong-coupling everything together in the first place?&#160; After all, the whole purpose of this design is to decouple each task from one another so that we can arrange them in any number of ways.&#160; All we’re really doing in this case is moving that coupling from the Task library to the Process library.</div> <div>&#160;</div> <div>To some extent, we will never really get around this problem.&#160; We may like to pretend that TaskB is decoupled from TaskA, but if TaskB requires some input that can only come out of TaskA, then this really isn’t the case.&#160; The important thing to note, however, is that TaskB shouldn’t care where this input comes from – so long as it gets it.&#160; The other important thing to note is that if TaskA produces this input, it shouldn’t care who uses it or what it’s purpose is.&#160; So from task A and B’s perspective, this dependency doesn’t exist.&#160; But from the processes perspective, it does.&#160; The question is: where is the best place to define this dependency?</div> <div>&#160;</div> <div>I say, put this logic in external data instead of in your code.&#160; Rather than create a large, complicated, compiled hierarchy of Process classes, define an XML schema and create a library of documents that define these bindings for you.&#160; Then, define an adapter or a factory that generates a generic Process object by parsing these XML files.</div> <div>&#160;</div> <div>Understand that both solutions are functionally equivalent.&#160; But making your application data-driven has a few distinct advantages:</div> <ol> <li>You can now alter the behavior of a process object without recompiling it.&#160; This means you can easily distribute hot-fixes and additional functionality. </li> <li>Third-party’s can more easily integrate with your application and extend it. </li> <li>The source of a Process’ XML can now come from any location.&#160; Loading them from a web server or a database instead of a local file system will have no impact on your system. </li> <li>You can easily write a library of adapters which can deserialize the process object from any number of formats.&#160; You are no longer tied down to any one data representation. </li> </ol> <p>Most importantly, however, your application now only reacts to changes in data.&#160; This is the way I think of it: imagine you have two machines that build houses based on schematics.&#160; One machine has a number of buttons on it.&#160; Each button builds a different house.&#160; If you want to build additional houses, you need to buy a new machine.&#160; Contrast that with a rival machine, which, has only one button but also has a scanner.&#160; The scanner can read schematics directly from any piece of paper so long as it adheres to a certain standard and can build any house that can be specified in a schematic.</p> <p>Wouldn’t you rather have the second machine?&#160; The beauty of writing data-driven applications is that at their core, you have created something akin to the second machine.&#160; You have decoupled the dependencies from your application so much that your program is now simply responding to input rather than replaying set procedures.&#160; This makes it far more versatile, and it’s why programming in the WPF is so much more pleasant than writing WinForms applications – because now you get to focus on modifying the data and the UI separately from each other.&#160; There is still a contract that the two sides need to adhere to, but your programming paradigm becomes much cleaner.</p> <p>Which is why, I always try and make my applications as data-driven as possible.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-7292879106441343971?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-26489593893943507092009-07-07T10:35:00.000-07:002009-08-19T10:37:06.150-07:00How Much Should You Mock?<p>I managed to incite a small riot a few weeks ago when I got involved in a somewhat heated debate internally about how far one should go with their unit testing.&#160; How much should you be mocking in your unit tests?&#160; Should you mock the file system?&#160; Should you mock a database?&#160; Should you mock calls to a web service?</p> <p>The basic problem is that at the lowest layers, you end up reaching a point where you must interact with an outside dependency.&#160; This is the point where there’s nothing left to mock: you have abstracted everything you possibly can and now you must interact with the outside world.&#160; The arguments many people make are, because the interaction with the external dependency is something that you don’t own, you can’t possibly simulate it’s behavior, and therefore you can’t test it.&#160; Or, because the dependency can’t be abstracted any further, that being able to test it is so difficult that there are no benefits to the extra work.&#160; Both of these are no doubt true on at least a few levels.&#160; What people prefer to do is wrap these dependencies with abstractions, and then test those abstractions rather than the boundaries.&#160; The last bit at least, I agree with completely.</p> <p>Here’s my problem.&#160; Often times, the reason that external dependencies are so hard to be test is because they’re not designed to be tested.&#160; Take the Tfs Client API, for instance.&#160; This is an insanely difficult library to test because it is filled with sealed objects that have non-virtual methods and private setters.&#160; Ack!&#160; The only way to test this is to mimic the hierarchy by using a nicely designed bridge pattern and reference the object model via our own abstractions.&#160; But this is not ideal.&#160; Why would we choose to wrap an API with a testable object model instead of using the actual object model?&#160; As long as we can mock the original hierarchy, this becomes a large waste of time and serves no purpose.</p> <p>Sadly, many of the boundaries in our applications run into walls just like this.&#160; And to me, this is the major reason that mocking them becomes so difficult.&#160; It’s not that there is no value in mocking these dependencies, it’s just that there’s no real practical way to do it most of the time.&#160; </p> <p>…but if there was, my question is: why would we choose not to?&#160; Just because it’s not our system doesn’t mean we shouldn’t try and test our interaction with it.&#160; Somewhere in our code, we are making assumptions that external systems are going to behave a certain way.&#160; They’re going to throw certain exceptions in certain cases, they’re going to return different values based on different inputs, etc.&#160; Because we have to code against these behaviors, why would we choose not to test against them, too?&#160; There are, perhaps, limits to our zealotry – but I don’t think that means we shouldn’t try.</p> <p>So my answer to the question is this: you should test and mock everything that you reasonably can.&#160; This is not a substitute for an integration test or a nicely layered design – it’s a companion to it.&#160; And my other plea is: remember that other people will be writing code against yours, so if you want their code to be robust, make sure your API is testable.&#160; If only it were easier to test the boundaries of my applications, that riot might have been avoided.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-2648959389394350709?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-1114545863869158002009-06-20T09:33:00.001-07:002009-06-20T09:33:07.123-07:00Random Weekend Thoughts<p>I’ve been rather busy at work, but have accumulated a number of thoughts over the last few months that I figured I’d share:</p> <p>1. For a software engineer, I know remarkably little about ANAMES, CNAMES, and other DNS related items.&#160; Hence, when the blog went down about one week ago, I was unable to diagnose it.&#160; And my resolution was to give up.&#160; Forget it.&#160; <a href="http://www.michaelbraude.com">www.michaelbraude.com</a> now just forwards to <a href="http://www.michaelbraude.blogspot.com">www.michaelbraude.blogspot.com</a>.&#160; Because it’s easier this way – and because, frankly, Yahoo’s domain hosting is terrible and blogger’s domain hosting help section is absolutely useless when it comes to setting up domains and resolving issues.&#160; My advice is to use anybody else.</p> <p>2. <a href="http://www.bing.com">Bing</a> is better.&#160; Yes I’m biased, but it’s still better.&#160; There is a palpable excitement within Microsoft after the Bing launch.&#160; It’s fun to be a part of that.</p> <p>3. On the heels of my <a href="http://michaelbraude.blogspot.com/2009/05/why-ill-never-be-web-guy.html">last rant</a>, a few things have occurred to me.&#160; First, one big reason people like thin clients such as web pages is because the number of alternatives right now is low.&#160; There are no rich clients that connect to the cloud and do things like Facebook or Twitter do.&#160; If there were, then people would prefer the rich client because it would be superior to the webpage in every way.&#160; Second, I am increasingly convinced that we have reached the end of what’s possible with HTML and JavaScript.&#160; There’s just not much more room for improvement.&#160; Google docs will never surpass Excel because, frankly, the technology is too limiting.&#160; And lastly, even if there were a bunch of killer cloud-based Windows applications that were superior to web pages, people would need a trivial way to a) find them and b) run them.&#160; Which is why we need a click-once application store for windows applications.&#160; Apple has shown that the appstore model is a good one.&#160; It makes it easy for people to find fun applications to run.&#160; Windows needs something similar.</p> <p>4. We need to give people a reason to want more powerful computers.&#160; If you’re browsing the internet, your 6 year old Athlon 1.4 GHz computer from 2003 will be fine.&#160; Having a library of rich, cloud-based applications will spur demand for faster machines (a 3D WPF-based Facebook app would be awesome!).</p> <p>5. Why is it so hard to find small laptops with high screen resolutions?&#160; Who wants a 16” screen with 1280x800 resolution?</p> <p>6. I love my XBox, but mostly because Nintendo is unable to publish enough games themselves to keep a gamer busy.&#160; Why is it that every time I go to Gamestop, the entire Wii wall is filled with games for 9 year old girls?&#160; Clearly there are adults who own Wii’s.&#160; Why isn’t anybody developing games for them?</p> <p>7. What crazy company would ever ship competitors’ products with their own?&#160; Imagine if Toyota gave you a “ballot” when you bought a car from them, from which you could “vote” on which car stereo you preferred – a Toyota stereo, or an after-market brand?&#160; No, this insanity makes no sense to anybody.&#160; That the EU is complaining about the browserless Windows 7 solution is an admission that, yes, a web browser <em>is</em> an integral part of the operating system.&#160; Which makes the whole bundling argument rather weak.&#160; But ship competitors products with your own?&#160; Forget it.&#160; I’d rather ship nothing.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-111454586386915800?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com7tag:blogger.com,1999:blog-5139324531203768210.post-7518029762147348002009-06-12T17:19:00.001-07:002009-06-12T17:19:28.738-07:00XmlSerializer Can’t Handle Interfaces (With a Workaround)<p>It didn’t occur to me until it was a bit too late, but XmlSerializer can’t handle interfaces.&#160; I understand why this is: how would the serializer know what class to instantiate that would return an instance of the interface type?&#160; But the lack of a built-in workaround here is a bit of an annoyance.&#160; Since I like to abstract things in ways that allow me to mock them, I separated the implementation of some of objects into interfaces, without realizing that this would break serialization.&#160; Even having your interface implement IXmlSerializable doesn’t solve the problem – you just end up with a different error that says something to the effect of, “System.InvalidOperationException: [class] cannot be serialized because it does not have a parameterless constructor.”&#160; This is because the serializer is expecting that whatever implements IXmlSerializable is a class and that it has a parameterless constructor.&#160; Obviously, interfaces won’t work in these cases.</p> <p>For instance, this property will fail to serialize:</p> <div id="codeSnippetWrapper"> <pre id="codeSnippet" class="csharpcode"><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Gets / sets the working folder shims.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br />[XmlElement] <br /><span class="kwrd">public</span> <span class="kwrd">virtual</span> IWorkingFolderShim[] Folders<br />{<br /> get;<br /> set;<br />}</pre> </div> <p>So in order to get around this, I had to do something hackish.&#160; It’s not that pretty, but it works:</p> <div id="codeSnippetWrapper"> <pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Gets / sets the working folder shims.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br />[XmlElement] <br /><span class="kwrd">public</span> <span class="kwrd">virtual</span> WorkingFolderShim[] FolderShims<br />{<br /> get;<br /> set;<br />}<br /><br /><span class="rem">/// &lt;summary&gt;</span><br /><span class="rem">/// Gets / sets the folder shims.</span><br /><span class="rem">/// &lt;/summary&gt;</span><br />[XmlIgnore]<br /><span class="kwrd">public</span> <span class="kwrd">virtual</span> IWorkingFolderShim[] Folders<br />{<br /> get<br /> {<br /> <span class="kwrd">return</span> <span class="kwrd">this</span>.FolderShims;<br /> }<br />}</pre> <p>The object where these properties are defined implements an interface that exposes the folders property – not the FolderShims property. That way, so long as people reference the object by its abstraction, the FolderShims property is hidden from them. The proper thing to do is to make the FolderShims property internal, but I hate unit testing with InternalsVisibleTo unless it’s really absolutely necessary.</p> </div> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-751802976214734800?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com3tag:blogger.com,1999:blog-5139324531203768210.post-16738666496159564332009-06-10T10:52:00.001-07:002009-06-10T10:52:38.099-07:00Snippets are a Life Saver<p>I occasionally keep forgetting how critical snippets are to my productivity.&#160; I actually keep a bunch of snippets on my Sky Drive so that I can port them over from one machine to another.&#160; With the help of snippets, some incredibly tedious tasks that would normally drive me nuts with boredom can be largely skipped with automation.</p> <p>There are a few major snippets that I use constantly – particularly with WPF applications.&#160; The first is the absolutely critical Dependency Property snippet (yes, I know Visual Studio ships with one of these, but I like mine much, much more):</p> <pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span> <span class="rem">/// Defines the $Name$Property dependency property.</span> <span class="rem">/// &lt;/summary&gt;</span> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty $Name$Property = DependencyProperty.Register(<span class="str">&quot;$Name$&quot;</span>, <span class="kwrd">typeof</span>($Type$), <span class="kwrd">typeof</span>($Owner$)); <span class="rem">/// &lt;summary&gt;</span> <span class="rem">/// Gets / sets the $Name$ property.</span> <span class="rem">/// &lt;/summary&gt;</span> <span class="kwrd">public</span> <span class="kwrd">virtual</span> $Type$ $Name$ { get <br /> { <span class="kwrd">return</span> ($Type$)GetValue($Name$Property); } set <br /> { SetValue($Name$Property, <span class="kwrd">value</span>); } }</pre> <p>This alone saves me hours of development time, since I don’t need to cut and paste this same code over and over again.&#160; But today, as I was painfully filling out some code to support the INotifyPropertyChanged interface, I realized that I should really make a snippet out of it to save me time.&#160; And so, I came up with this:</p> <pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span> <span class="rem">/// Defines the $Name$ property value.</span> <span class="rem">/// &lt;/summary&gt;</span> <span class="kwrd">private</span> $Type$ m$Name$; <span class="rem">/// &lt;summary&gt;</span> <span class="rem">/// Gets / sets the name of the argument.</span> <span class="rem">/// &lt;/summary&gt;</span> <span class="kwrd">public</span> $Type$ $Name$ { get { <span class="kwrd">return</span> m$Name$; } set { <span class="kwrd">this</span>.m$Name$ = <span class="kwrd">value</span>; <span class="kwrd">this</span>.FirePropertyChanged(<span class="str">&quot;$Name$&quot;</span>); } }</pre> <p>Of course, this assumes that you’ve defined the FirePropertyChanged method somewhere in your class, which is very simple and usually just looks like this:</p> <pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span> <span class="rem">/// Fires the PropertyChanged event.</span> <span class="rem">/// &lt;/summary&gt;</span> <span class="rem">/// &lt;param name=&quot;propertyName&quot;&gt;The name of the property that changed&lt;/param&gt;</span> <span class="kwrd">private</span> <span class="kwrd">void</span> FirePropertyChanged(<span class="kwrd">string</span> propertyName) { <span class="kwrd">if</span> (<span class="kwrd">this</span>.PropertyChanged != <span class="kwrd">null</span>) <span class="kwrd">this</span>.PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(propertyName)); }</pre> <p>So this experience has reminded me that whenever I end up doing some mindless, repetitive task over and over again, I should write a snippet for it.&#160; Too bad the <a href="http://www.codeplex.com/SnippetEditor">snippet editor</a> isn’t part of Visual Studio 2008.&#160; It’s relatively baffling that we have a built-in snippets manager, but not a snippets editor.&#160; I should double check what we’ve got coming up in 2010…</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-1673866649615956433?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com3tag:blogger.com,1999:blog-5139324531203768210.post-74459877763014201192009-06-04T11:02:00.001-07:002009-06-04T12:10:14.265-07:00How I’m Running My First Sprint<p>The project I’m working on has just started to get serious.&#160; When projects are small, keeping track of your tasks and priorities is easy, because the scope of your project is small and what you need to do is obvious.&#160; But as soon as things get larger and people start to expect certain things from what you’re doing, that ad-hoc approach to software development doesn’t work any more.&#160; That’s when your process really becomes valuable.</p> <p>Before I came to Microsoft, I worked with a team that did an excellent job executing an agile process.&#160; Our scrums were well-run and it was always clear what our status was.&#160; If we were falling behind, problems and roadblocks were immediately obvious.&#160; What I love about agile is that it frees you from bureaucracy but still chains you to the ground.&#160; You can’t get too far ahead of yourself either by going off on unnecessary tangents, but you also don’t need to burden yourself by demanding that you know everything ahead of time.&#160; It’s both liberating and grounding at the same time.</p> <p>The product that I’m developing right now is largely unknown, so agile is the perfect process to develop my project with.&#160; And while I might be the only person working on it right now, I don’t anticipate it being that way forever.&#160; So in order to make my process more formal and organized, I decided to hold my own scrums and manage my own sprint – even though there’s only one person involved right now.&#160; I figure that it’s good practice for the future when more people are involved.</p> <p>So the first steps I took towards running my own scrums were the following:</p> <ol> <li><strong>Enter requirements into TFS <br /></strong>My requirements engineering process in this case was pretty half-hearted.&#160; Most of my requirements are still very undefined.&#160; I wrote a number of use cases a while ago, which are sitting in a OneNote notebook on my computer.&#160; These helped me make some basic architecture decisions.&#160; But I’m past that stage now.&#160; The requirements, or “Scenarios” as TFS wants to call them, are work items that describe overlying goals.&#160; It’s critical that these get written down somewhere.&#160; Otherwise, the next step has much less meaning. <br /></li> <li><strong>Put items in a backlog <br /></strong>Next, I created a list task work items and put them in an iteration path that ended in Backlog.&#160; I tied each work item to a requirement.&#160; This is a very important step.&#160; If a work item did not fall into the domain of a requirement, then I either had to question the wisdom of the work item or add a requirement that I hadn’t defined yet.&#160; The important rule for me is that every work item in my backlog corresponds to a requirement.&#160; This makes sure that I never put work into my queue that is not part of an overlying goal – so I can’t get distracted.&#160; The other benefit of this is that if I open my requirement work item, I can see a list of every work item that is associated with that requirement.&#160; Even better: when I check things into TFS and attach the changeset to work items, I can now follow the chain all the way back to a requirement.&#160; Very cool. <br /></li> <li><strong>Design a sprint template <br /></strong>Now here’s where things get strange.&#160; There are of course a number of free templates on the internet that you can draw from, but I found that most of these tailor to specific people’s specific process.&#160; My process is inherently different from other people’s.&#160; For instance, for my money, there’s only a few things that I really care about graphing: the burn down line, and the amount of time left to complete my tasks.&#160; Initial estimates are interesting, but to me they are ultimately only useful from a post-mortem perspective.&#160; They don’t help me from a tracking and planning perspective. <br /> <br />Velocity is an interesting statistic to track.&#160; But I ultimately don’t care so much about it because I figure that my time-left estimate should take into account my velocity.&#160; For instance, if a task would normally take me half a day to complete, but I’m swamped with some other issue that will delay me by two days, I would expect my time-left on that task to be 2.5 days – not .5 days.&#160; So velocity, as a statistic, should be backed into my time-left numbers. <br /> <br />My underlying principle for the sprint template was: keep it simple.&#160; Don’t overburden the sprint with too much data.&#160; All I’m really interested in is, am I on track to finishing these work items by the end of the sprint or not?&#160; Other things I don’t care so much about. <br /> <br />So I started by importing a TFS query into an Excel spreadsheet which automatically populated it with my current sprint work items.&#160; The only columns that I’m interested are: work item ID, title, assigned to and remaining work.&#160; I then filled out a simple table that I fill in every day with my current work estimates.&#160; Lastly, I replaced the “remaining work” values in the TFS table with an Excel function that automatically fills it in with my latest estimates.&#160; That way, when I save the spreadsheet, the work items get updated with my latest estimates.</li> </ol> <p>The end result looks like this:</p> <p><a href="http://lh6.ggpht.com/_e966vsQhLfE/SigcFB-RYXI/AAAAAAAAARc/jZpue6m1kTE/s1600-h/Sprint%5B19%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Sprint" border="0" alt="Sprint" src="http://lh5.ggpht.com/_e966vsQhLfE/SigcFU9zq7I/AAAAAAAAARg/qVA0IDFgzp4/Sprint_thumb%5B14%5D.jpg?imgmax=800" width="644" height="316" /></a> </p> <p>I anticipate, of course, that I will continue to refine this as time goes on.&#160; But for now, this process is working very well.&#160; As you can see from my chart, I’ve already learned a few important things so far about my current sprint.&#160; First, I have a much higher capacity than I thought I did when I started the sprint.&#160; Second, my initial estimates tend to be more pessimistic than they should be.&#160; I suppose I’m a fast worker.&#160; But without metrics like the chart above, I would never know for sure.&#160; In a few days, depending on where I am, I will know whether I have the time to add more tasks into this sprint or not.&#160; </p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-7445987776301420119?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com2tag:blogger.com,1999:blog-5139324531203768210.post-6742936492551929062009-05-29T18:11:00.001-07:002009-08-17T14:01:59.764-07:00Why I’ll Never Be A ‘Web Guy’<p>If popular culture is right, then I’m in for a disappointing career.&#160; That’s because most people think that “everything is moving to the web,” and if that’s the case, then I can’t imagine being happy as a software engineer for the rest of my life.&#160; So for my sake, I really hope everybody’s wrong.</p> <p>I’m continually bombarded with questions from friends and other folks why I don’t want to work for an Internet company.&#160; Most of them don’t understand.&#160; When they look around at innovation in the software industry, they see cell phones and flashy web pages.&#160; Nobody sees the awesome stuff going into the .NET framework, or, sadly, the amazing things you can develop on top of it (where are all those awesome WPF applications I’ve been waiting for?).&#160; There’s a reason I work where I do.&#160; As far as I’m concerned, the people I work with are doing the most innovative and amazing things on the planet.&#160; What a thrill it is to be a part of it.</p> <p>But why not the Internet?&#160; The reason is that it’s the most aggravating place in the world to write commercial software for.&#160; You have, off the top of my head, 4 major web browsers to deal with across at least two operating systems.&#160; Each of these scenarios requires its own set of tests, and each browser will behave slightly differently depending on what OS it’s running on and what browser version it is running.&#160; And then there’s mobile.&#160; Want your website to look good on a cell phone?&#160; Have fun: now you get to render a different page for every cell phone model in existence.&#160; And just in case this wasn’t unpleasant enough, the debugging and diagnostic tools for most of these environments are non-existent.&#160; That means you get to guess why a page renders funny or a random JavaScript error occurs, because you really have no way of figuring it out in a procedural, and scientific way (get ready for liberal use of Window.Alert).</p> <p>Most of us have gotten used to the civilized world where we have compilers, IDEs, object orientated languages and debuggers.&#160; We have strong-typing, class inheritance, and plenty of system resources at our disposal.&#160; It’s a challenging place to be.&#160; We can write things to disk, spawn multiple threads and render in 3D.&#160; There’s no limit to what we can do.&#160; And yet, most people seem to want to program in a limiting box called a web browser in a ‘language’ called HTML.</p> <p>But then, that’s just it, isn’t it?&#160; The reason most people want to program for the web is that they’re not smart enough to do anything else.&#160; They don’t understand compilers, concurrency, 3D or class inheritance.&#160; They haven’t got a clue why I’d use an interface or an abstract class.&#160; They don’t understand: virtual methods, pointers, references, garbage collection, finalizers, pass-by-reference vs. pass-by-value, virtual C++ destructors, or the differences between C# structs and classes.&#160; They also know nothing about process.&#160; Waterfall?&#160; Spiral?&#160; Agile?&#160; Forget it.&#160; They’ve never seen a requirements document, they’ve never written a design document, they’ve never drawn a UML diagram, and they haven’t even heard of a sequence diagram.</p> <p>But they do know a few things: they know how to throw an ASP.NET webpage together, send some (poorly done) SQL down into a database, fill a dataset, and render a grid control.&#160; This much they’ve figured out.&#160; And the chances are good it didn’t take them long to figure it out.</p> <p>OK, so that’s not an entirely fair accusation to make.&#160; Of course there are smart people who like to work on the web, and who find challenging things about it.&#160; But I would argue that most people aren’t in this category.&#160; For proof, try interviewing people who have lots of web experience, and contrast them with people who have lots of application experience.&#160; In every case I’ve seen, candidates with application experience are often far better engineers than candidates with lots of web expertise.</p> <p>So forgive me for being smarmy and offensive, but I have no interest in being a ‘web guy’. And there are two reasons for this.&#160; First, it’s not a challenging medium for me.&#160; And second, because the vast majority of Internet companies are filled with bad engineers – precisely because you don’t need to know complicated things to be a web developer.&#160; As far as I’m concerned, the Internet is responsible for a collective dumbing down of our intelligence.&#160; You just don’t have to be that smart to throw up a webpage.</p> <p>So I really hope everybody’s wrong and everything doesn’t ”move to the web.”&#160; Because if it does, one day I will either have to reluctantly join this boring movement, or I’ll have to find another profession.</p> <p><strong>Update 8/17/2009</strong> – In response to a plethora of criticisms, especially one by the esteemed Jeff Atwood, I have posted a <a href="http://michaelbraude.blogspot.com/2009/08/re-all-programming-is-web-programming.html">reply on the blog</a>.&#160; I don’t expect it to please everybody, but it will hopefully clarify what I was intending to say the first time around.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-674293649255192906?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com157tag:blogger.com,1999:blog-5139324531203768210.post-25638628788549740472009-05-20T15:30:00.001-07:002009-05-20T15:30:22.491-07:00Annoying Gotcha #230<p>Ack, is this annoying.&#160; The following code will almost certainly cause problems for you if you’re not careful:</p> <pre class="csharpcode"><span class="kwrd">using</span> (XmlReader reader = XmlReader.Create(File.Open(path, FileMode.Open))) { ... }</pre> <p>Why does this cause problems?&#160; Because the default XmlReaderSettings passed into the Create overload does not have the CloseInput property set to true.&#160; This means that the file handle is <em>not</em> disposed of at the end of the using block – and it means that some other program, later on, can very easily run into IOExceptions when it tries to open the same file and gets blocked because another program never closed a file handle.</p> <p>Of course the way around this is easy:</p> <pre class="csharpcode">XmlReaderSettings settings = <span class="kwrd">new</span> XmlReaderSettings(); settings.CloseInput = <span class="kwrd">true</span>; <span class="kwrd">using</span> (XmlReader reader = XmlReader.Create(File.Open(path, FileMode.Open), settings)) { ... }</pre> <p>But the amount of time I’ve wasted in the last few days figuring out what’s going on before I was reminded that this is not the default behavior is rather depressing.&#160; Why this isn’t the default setting, I can only guess.&#160; I expect that when a stream is disposed, every stream that it decorates is also disposed.&#160; Hence, passing in an XmlSettings object shouldn’t be necessary.&#160; reader.Dispose() implies that the stream passed into the reader is also disposed.</p> <p>But maybe what aggravates me the most is inconsistent behavior.&#160; Most streams close their inner streams when they are disposed.&#160; So why should XmlReader be any different?</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-2563862878854974047?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com3tag:blogger.com,1999:blog-5139324531203768210.post-14815936287083843182009-05-13T15:18:00.001-07:002009-05-13T15:18:06.568-07:00Styling a Window Background With a Logo<p>I finally have a chance to get working with the WPF again.&#160; It’s been a long time, and it’s funny how quickly you both forget and remember things.&#160; A lot of time all I need is a quick look at a reference book and my memory kicks in.&#160; And then there are those things that you wonder how you ever understood in the first place.</p> <p>I had a friend of mine whip up a simple logo / icon for my current project.&#160; It’s super slick looking, and I want to get it into whatever windows and dialogs and webpages that I can.&#160; Nice UI’s make your work look professional, and if there’s one thing I’ve learned about software, it’s that first impressions make a lasting impact.&#160; All it takes are a few wiz-bang, flashy effects and your customers are instantly impressed.&#160; Of course, you still need to deliver…but that’s another issue.</p> <p>So I had a great idea to use the logo as the background for all of my windows by using some styles and a VisualBrush.&#160; It’s funny how a seemingly simple project could wrack your brain for a few hours.&#160; The main problem was that, for some reason, there is no trivial way to set the filler background color for a VisualBrush, and so it defaults to black.&#160; So say, for example, that your logo .xaml resource is ~150 x ~76.&#160; What you want is for the visual to be drawn in the center of the window, uniform scaled (so that there’s no distortion), with the rest of the background color set to whatever other color you want.&#160; Since it’s very unlikely that your windows will be sized to exactly fit the 150 x 76 dimensions of the logo, there will inevitably be some dead space in your window.&#160; And what you can’t have is for the background color of the logo to be different from the background color of that dead space.</p> <p>The other alternative is to scale your logo to either Fill or UniformToFill.&#160; But neither of those options are ideal.&#160; One distorts the logo, and the other will end up clipping much of it off screen.&#160; So you end up having to do some canvas-within-a-canvas scaling magic to get it working properly:</p> <pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ResourceDictionary</span> <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><span class="kwrd">&gt;</span> <span class="rem">&lt;!-- The logo was exported into .xaml from Adobe Illustrator --&gt;</span> <span class="rem">&lt;!-- It is defined in a ResourceDictionary as a Canvas with x:Key=&quot;Logo&quot; --&gt;</span> <span class="kwrd">&lt;</span><span class="html">ResourceDictionary.MergedDictionaries</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">ResourceDictionary</span> <span class="attr">Source</span><span class="kwrd">=&quot;..\ResourceDictionaries\Logo.xaml&quot;</span> <span class="kwrd">/&gt;</span> <span class="kwrd">&lt;/</span><span class="html">ResourceDictionary.MergedDictionaries</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;WindowStyle&quot;</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;{x:Type Window}&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Background&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">VisualBrush</span> <span class="attr">Stretch</span><span class="kwrd">=&quot;UniformToFill&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">VisualBrush.Visual</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Canvas</span> <span class="attr">Width</span><span class="kwrd">=&quot;100&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;100&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;White&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Canvas</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;2&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;2&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;96&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;96&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Canvas.Background</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">VisualBrush</span> <span class="attr">Visual</span><span class="kwrd">=&quot;{StaticResource Logo}&quot;</span> <span class="attr">Stretch</span><span class="kwrd">=&quot;Uniform&quot;</span> <span class="attr">Opacity</span><span class="kwrd">=&quot;.25&quot;</span> <span class="kwrd">/&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Canvas.Background</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Canvas</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Canvas</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">VisualBrush.Visual</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">VisualBrush</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Icon&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;..\Logo.ico&quot;</span> <span class="kwrd">/&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;/</span><span class="html">ResourceDictionary</span><span class="kwrd">&gt;</span></pre> <p>This looks trivial, but the trick was to realize that the logo’s canvas needed to be placed inside another canvas that was UniformToFill.&#160; Any other value and the logo ends up distorted.&#160; For instance, if the outer VisualBrush is set to Fill, then the inner logo ends up being stretched even though it’s set to Uniform.&#160; Setting it to None or Uniform doesn’t work either, because the result is black-colored dead-space.&#160; But setting the outer to UniformToFill causes it to expand to cover the entire background of the window, while the inner canvas’ content is resized to fit the space it’s given.</p> <p>There may be a better way to do this, I don’t know.&#160; But for now the logo is looking pretty slick.&#160; So I’m going to keep it this way.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-1481593628708384318?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0tag:blogger.com,1999:blog-5139324531203768210.post-38160812371749667042009-04-29T10:47:00.001-07:002009-04-29T10:47:32.240-07:00The Value of UML<p>I appear to be a dying breed.&#160; I am one of the few people who really seems to value strong use of UML.&#160; And it perplexes me to death why nobody else cares about drawing things out before they code.</p> <p>Complex software systems are hard to understand, but they become a thousand percent easier when you can see class relationships with your own two eyes.&#160; Suddenly, a design either make sense or it doesn’t at all.&#160; In either case, visualizing a system in graphical form makes it easy to spot the pros and cons of your design and understand where to make changes.&#160; Without UML, you’re just looking at a lot of loosely connected text files.</p> <p>And yet, nobody seems to care about drawing things out.&#160; Any argument that up-front design takes more time than none at all is short-sighted as any experienced engineer will tell you.&#160; It will take you longer to skip design altogether because your lack of foresight will cause delays later on.&#160; You know how people tell you to think before you speak?&#160; Well, I say, think before you code.</p> <p>My suspicion is that the agile movement has somehow convinced everybody that it’s OK to skip drawing UML.&#160; Maybe all those old, out of date UML diagrams sitting on your backup server have convinced you not to bother with it at all.&#160; But when you are starting a brand new project, UML helps you visualize a class hierarchy of your systems foundation before you even start writing it.&#160; So while there may not be much value in staring at an old UML diagram that hasn’t been updated in 3 years, there is a lot of value in staring at a UML diagram for a new system that doesn’t exist yet.&#160; And for new systems, it’s just so critical to get the foundation right.&#160; A system’s effectiveness will stem directly from the basic architecture on which it was founded.&#160; Screw that up, and your software will be screwy.</p> <p>So here’s where UML fits into my agile process.&#160; During the design phase of my sprint, I spend 2-3 days drawing UML on a whiteboard.&#160; I don’t get it perfect.&#160; I don’t get every property and every method and every parameter right – but I get the basic classes and relationships down.&#160; And this process forces me to think about how everything is going to fit together so that they meet my requirements.&#160; Because it’s on a whiteboard, I can refactor with the stroke of an eraser.&#160; Class names and relationships change every few seconds.&#160; I can visually see the problems with my design, and I can visually find a way to fix it.&#160; Then, once I’m done, I take a picture, save it, and start coding (using TDD of course).</p> <p>What happens to the picture?&#160; I can hold onto it or not.&#160; Nobody knows how accurate it will be in a few years.&#160; But my opinion is that if the design was right in the first place, it won’t be necessary for people to have an up-to-date picture there all the time.&#160; And if people need to modify the design, it will likely be more useful to redraw the UML as things exist at the time they are being redesigned.&#160; The relationships will be more complex in the future than they are now, which means the UML I draw today will be so out of date for tomorrows redesigns that there’s little point in holding onto it for a long time.</p> <p>But the point is: UML is still an important part of the process, and it should not be skipped.&#160; You can have UML in an agile process, and in fact, I think they go very well together.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5139324531203768210-3816081237174966704?l=www.michaelbraude.com' alt='' /></div>Michael J. Braudehttp://www.blogger.com/profile/03925868482949362877mikebraude@gmail.com0