<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-24760385</atom:id><lastBuildDate>Tue, 27 Apr 2010 08:25:18 +0000</lastBuildDate><title>NET Progress</title><description>John Rusk's notes on .NET Programming</description><link>http://dotnet.agilekiwi.com/blog/</link><managingEditor>noreply@blogger.com (John Rusk)</managingEditor><generator>Blogger</generator><openSearch:totalResults>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3217678055236384608</guid><pubDate>Tue, 27 Apr 2010 08:13:00 +0000</pubDate><atom:updated>2010-04-27T01:13:09.408-07:00</atom:updated><title>This blog -- taking a break</title><description>Prompted, in part, by my annoyance at Google dropping the FTP support this blog relies on, but mostly by a lack of time, I won't be doing any work on this blog for the foreseeable future.&lt;br /&gt;&lt;br /&gt;Commenting on all posts will be disabled.&lt;br /&gt;&lt;br /&gt;However I do have plans to write new material on &lt;a href="http://www.agilekiwi.com/"&gt;my other "non-technical" blog&lt;/a&gt;, especially about "people skills for geeks". &amp;nbsp;(A topic on which I recently posted&lt;a href="http://www.youtube.com/watch?v=e38dxRcySHI"&gt; this video&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Thanks to everyone who's read and commented on this blog over the past 4 years.&lt;br /&gt;&lt;br /&gt;-- John&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3217678055236384608?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2010/04/this-blog-taking-break.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-1239422429940943275</guid><pubDate>Tue, 27 Apr 2010 08:00:00 +0000</pubDate><atom:updated>2010-04-27T01:20:16.241-07:00</atom:updated><title>Memory Leaks in Managed Code</title><description>&lt;i&gt;(This is a repost of an old article I wrote in early 2006, before I started this blog)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;When writing a Window Forms application, it's useful to display the current memory usage in the "About" box.  It comes in handy when trouble shooting.  It usually proves that memory usage it not the problem, but sometimes it proves the opposite: the application is chewing up more and more RAM.&lt;br /&gt;&lt;br /&gt;How can that be?  How can a managed application leak memory?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Types of Managed Memory Leaks&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There are two main types of "leak" in managed applications&lt;br /&gt;&lt;br /&gt;1.  Unintended references keeping managed objects alive&lt;br /&gt;&lt;br /&gt;You're not using an object any more, so you expect that the garbage collector will clean it up.  But the garbage collector doesn't.  Why?  There is only one possible reason:  something, somewhere, still has a reference to the object.  Perhaps you put the object in some global (i.e. static) list or perhaps it is referred to be some other object which you are still using.&lt;br /&gt;&lt;br /&gt;So this isn't a "real" leak at all, it just looks like one.  You've forgotten about a reference to your object, but the garbage collector hasn't.   It sees the reference and keeps the object alive.&lt;br /&gt;&lt;br /&gt;Of course, a reference only counts if it can be (recursively) traced back to a "root" object which is still in use - i.e. a static field or a local variable/parameter in a currently executing method.  References from other objects which are, themselves, due for garbage collection will not keep an object alive.  In fact, the garbage collector never even sees them.  (It just starts from the roots and recursively visits reachable objects.) &lt;br /&gt;&lt;br /&gt;Event handlers are a common cause of this problem.  You create objects A and B then run some code like this: &lt;br /&gt;&lt;br /&gt;A.SomeEvent += new EventHandler(B.SomeMethod)  &lt;br /&gt;&lt;br /&gt;Later, you finish using B, but you're still using A.  Your on-going use of A keeps B alive, since A refers to B by way of the event handler.  If you want B's lifetime to be shorter than A's, you have to unhook the event handler with a  line like this:  &lt;br /&gt;&lt;br /&gt;A.SomeEvent -= new EventHandler(B.SomeMethod)    &amp;nbsp;//note the '-='&lt;br /&gt;&lt;br /&gt;Of course, event handlers aren't the only cause of this problem, any reference between objects will do.  Consequently, these problems can be difficult to track down.   You can't think what the remaining reference is, but there must be one there, somewhere.  To help track it down try a tool like&lt;a href="http://www.memprofiler.com/"&gt; SciTech .NET Memory Profiler&lt;/a&gt;.  Or, if you  prefer free development tools, try Microsoft's &lt;a href="http://blogs.msdn.com/joncole/archive/2005/12/15/505627.aspx"&gt;SOS debugger extension&lt;/a&gt;.  But be warned, it can be &lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/06/Bugslayer/"&gt;a bit &lt;/a&gt;&lt;a href="http://blogs.msdn.com/tess/archive/2005/11/25/496973.aspx"&gt;complicated&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;2. Managed objects holding unmanaged resources&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are two variants of this problem:&lt;br /&gt;&lt;br /&gt;(a) Badly-written managed objects, which don't clean-up after themselves.  Of course, you don't write any of these, so let's move straight on to (b)…&lt;br /&gt;&lt;br /&gt;(You don't write bad objects because you know that a good managed object should always implement IDisposable if it uses unmanaged resources.  A good managed programmer will use that interface to clean the object up when he or she has finished with it. IF the programmer forgets, the good managed object will &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconFinalizeDispose.asp"&gt;clean up the unmanaged resources anyway &lt;/a&gt;when the garbage collector collects the object. )&lt;br /&gt;&lt;br /&gt;(b) Small managed objects, which use significant amounts of unmanaged memory.  The .NET 1.1 garbage collector cannot see the unmanaged memory.  It just sees the small managed part, so it thinks there's no need for a collection.  (If it did do a collection, the well-written managed object would indeed free the unmanaged memory, but the garbage collector doesn't realise a collection is required.). &lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/ericgu/archive/2003/12/08/52964.aspx"&gt;Bitmaps are a classic example of this problem&lt;/a&gt;, since they have a small managed component and a large unmanaged part.  Under .NET 2.0, there is a &lt;a href="http://msdn2.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx"&gt;new method&lt;/a&gt; which such objects can call to inform the garbage collector of their true size.  It will solve this problem (as long as it's used correctly).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other Types of Managed Memory Problems&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Two other leak-like problems are possible (although relatively unlikely, in practice, I'd say).  The first relates to "pinned" objects preventing the garbage collector from moving objects around.  This is an internal .NET implementation issue, and has been &lt;a href="http://blogs.msdn.com/maoni/archive/2005/10/03/476750.aspx"&gt;significantly improved&lt;/a&gt; in .NET 2.  The second relates to declaring lots of large objects and never letting them leave scope.  In the unlikely even that you find yourself doing that - and suffering unacceptable memory usage - you should stop doing it  :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;318263"&gt;This page&lt;/a&gt; itemizes all the kinds of memory leaks that I've listed here (although it fails to mention managed objects holding unmanaged resources).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What to Do&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Always examine memory usage when you test your application.  Don't assume everything will be OK simply because you're using managed code.  Test it.&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you're writing a GUI application, consider displaying both managed and unmanaged memory usage in the About box, using GC.GetTotalMemory(true) and Process.GetCurrentProcess().PrivateMemorySize respectively.   (See &lt;a href="http://discuss.develop.com/archives/wa.exe?A2=ind0404b&amp;amp;L=dotnet-clr&amp;amp;T=0&amp;amp;F=&amp;amp;S=&amp;amp;P=1298"&gt;this page&lt;/a&gt;, and &lt;a href="http://shsc.info/WindowsMemoryManagement"&gt;this one&lt;/a&gt;, for an explanation of exactly what PrivateMemorySize means.)  Open the About box from time to time during your testing, to check that the figures look reasonable.&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Call Dispose on IDisposable objects when you have finished with them.  If an object implements IDisposable it is saying "please clean me up when you've finished with me".   The object may hold unmanaged memory, or other resources such as files or GDI handles.  Call Dispose() or get the using statement to do it for you.&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Be careful with global (static) members.  Don't overuse them.  Why?  If you have a lot of statics, you may find it harder to understand which of them are keeping objects alive.  (This recommendation is for your benefit, not the garbage collector's.)&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Get to know your garbage collector.  &lt;a href="http://msdn2.microsoft.com/en-us/library/f144e03t.aspx"&gt;Here's&lt;/a&gt; a good starting point and some &lt;a href="http://msdn.microsoft.com/msdnmag/issues/1100/GCI/default.aspx"&gt;more advanced stuff&lt;/a&gt; too.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;What NOT to Do&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In general, &lt;a href="http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx"&gt;do not call GC.Collect(&lt;/a&gt;).  Leave it to the garbage collector to decide when a collection is required.  Having said that, I like to force a collection when my About box opens, to ensure the figures are accurate.  (Here's how to &lt;a href="http://blogs.msdn.com/tess/archive/2006/02/02/523597.aspx"&gt;force a complete collection&lt;/a&gt; - but like I said, you should almost never do so.)&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Don't null-out local variables.   In general, there is no need to set local variables to null when you have finished using them.  In Release builds (&lt;a href="http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/2e8905a8df28e9eb"&gt;unlike Debug builds&lt;/a&gt;), a local variable becomes eligible for garbage collection immediately after the last line that uses it.  If you add a line after that, to set the variable to null, the new line does no good.  It will either (very slightly) &lt;a href="http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/79c01b1bccc5ce1f"&gt;extend the lifetime of the object&lt;/a&gt; or it will have no effect at all (if the JIT compiler realizes the line is useless and optimizes it away).  So keep your code clean and readable by avoiding pointless assignments to null. &lt;i&gt;(When should you set things to null?  I can think of a couple of situations: (1) When a small object with long lifetime refers to a large object with a short lifetime.  Say you have two objects, A and B, and A contains a field that refers to B.  If B is a very large object and you want its lifetime to be significantly shorter than that of A, then consider setting the field to null when you've finished with B.  But don't go overboard - you probably won't need to do this very often.  (2) Another situation, relating specifically to servers with threads waiting on external resources,is &lt;a href="http://blogs.msdn.com/ricom/archive/2003/12/04/41281.aspx"&gt;described her&lt;/a&gt;e. Make sure you read the comments at the end.)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Don't get paranoid about garbage collector performance.  It is easy to underestimate just how good the .NET garbage collector is.  For instance, how many developers realise that a .NET app can create and destory around &lt;a href="http://msdn.microsoft.com/library/en-us/dndotnet/html/fastmanagedcode.asp"&gt;50 million small, short-lived objects per second&lt;/a&gt;!  (Admittedly, small-shortlived objects is the garbage collector's best-case scenario - but it also happens to be the most common scenaio in real world apps.)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-1239422429940943275?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2010/04/memory-leaks-in-managed-code.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-5371946381729804330</guid><pubDate>Fri, 15 Jan 2010 22:08:00 +0000</pubDate><atom:updated>2010-04-27T01:20:09.097-07:00</atom:updated><title>Debugging IEnumerable</title><description>I often find enumerables difficult to inspect in the debugger.  Here's a trick I just discovered.&lt;br /&gt;&lt;br /&gt;Given:&lt;br /&gt;&lt;br /&gt;IEnumerable&lt;sometype&gt; foo = ...&lt;br /&gt;&lt;br /&gt;you can inspect it more easily by first writing this in the Immediate Window:&lt;br /&gt;&lt;br /&gt;foo = foo.ToList()&lt;br /&gt;&lt;br /&gt;Press Enter in the immediate window, and foo changes from a (lazily) evaluated list (which is hard to inspect) into a real List&lt;sometype&gt; which you can easily inspect by just hovering over it's Non-public members -&amp;gt; items.&lt;/sometype&gt;&lt;/sometype&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-5371946381729804330?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2010/01/debugging-ienumerable.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-8770506694354293482</guid><pubDate>Mon, 26 Oct 2009 00:57:00 +0000</pubDate><atom:updated>2010-04-27T01:20:03.632-07:00</atom:updated><title>Exporting High-Res Graphics from Excel</title><description>I've recently been battling with technology, trying to save some Excel charts as high-res (900 dpi) files.&lt;br /&gt;Here's the technique I finally came up with. &amp;nbsp;(It also works for PowerPoint slides).:&lt;br /&gt;1. Save the chart as a PDF from Office (The PDF output is vector-based, so is very high quality)&lt;br /&gt;2. Use a command line line, this, to use Ghostscript to convert the PDF to a suitable tiff file. &amp;nbsp;(In my case, I want the final images to be 4 inches wide, at 900 dpi, but here I have specified an output size of 5 inches (72 * 5 = 360), then I'll crop the images back to 4in in the next step.)&lt;br /&gt;gswin32c -dSAFER -dBATCH -dNOPAUSE -sFONTPATH="E:\windows\fonts" -sDEVICE=tiffgray -r900 -dDEVICEWIDTHPOINTS=360 -dDEVICEHEIGHTPOINTS=221  -dPDFFitPage -sOutputFile=%~n1.tiff %1&lt;br /&gt;&lt;br /&gt;Key parameters are -dPDFFitPage, to cause resizing when using PDFs ans input, the DEVICExPOINTS to set the size of the output in points (1/72 ths of an inch), and -r to set the DPI.&lt;br /&gt;3. Finally, open the tiff in Photoshop (or similar) to crop and make any other final adjustments, then save from Photoshop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-8770506694354293482?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2009/10/exporting-high-res-graphics-from-excel.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3725162168224756516</guid><pubDate>Mon, 31 Aug 2009 09:12:00 +0000</pubDate><atom:updated>2010-04-27T01:19:58.234-07:00</atom:updated><title>Fix the Cross Functional Button on Toshiba Portege M200</title><description>I recently bought a second-hand Toshiba M200 tablet PC.  It's great!&lt;br /&gt;&lt;br /&gt;I just had one problem, the little 4-way button, which looks like a mini joystick and is technically known as the "Cross Functional Button", basically didn't work.  It was more of a non-functional button, really.&lt;br /&gt;&lt;br /&gt;It is supposed to allow you to scroll in all 4 directions, which is a very important thing when in tablet mode, because you don't have access to the keyboard.  But, it just output numbers instead of scrolling.&lt;br /&gt;&lt;br /&gt;I searched and searched and found nothing particularly helpful.  Eventually I went to the Toshiba site, found the "Toshiba Tablet PC Buttons Driver", installed it, and my problem was solved! &lt;br /&gt;I have no idea why, out of all the pages I searched, no-one mentioned this. &amp;nbsp;I found one where someone had the exact same problem, but resorted to a much more complicated solution. &amp;nbsp;So, this post is here for the next person who has the same problem. &amp;nbsp;Hopefully, you'll find this post and save yourself the hours of frustration that I had. &amp;nbsp;Just install the driver ;-)&lt;br /&gt;PS while you're there, install the accelerometer driver too, if you have &lt;a href="http://www.technologyquestions.com/technology/windows-xp-tablet-pc-newsgroup/2877-screen-orientation.html"&gt;this&lt;/a&gt; problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3725162168224756516?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2009/08/fix-cross-functional-button-on-toshiba.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-5164363880808405326</guid><pubDate>Sat, 31 Jan 2009 20:30:00 +0000</pubDate><atom:updated>2010-04-27T01:19:53.046-07:00</atom:updated><title>Things I'd like to see in the Entity Framework</title><description>With the announcement that the Entity Framework (aka EF or LINQ to Entities) &lt;a href="http://dotnet.agilekiwi.com/blog/2008/11/future-of-linq-to-sql.html"&gt;will become&lt;/a&gt; the favoured Microsoft ORM, many people have blogged about how important it will be for EF to achieve better ease-of-use in .NET 4.0.&lt;br /&gt;I'd like to add my 2c worth on what I think EF should include. (By the way, I've never worked with EF, and won't until at least the .NET 4 version, so for all I know some of these things might be present already. Basically, this list is my attempt to capture some of the lesser-known lessons learned from using LINQ to SQL.)&lt;br /&gt;&lt;b&gt;1. Metamodel&lt;/b&gt;&lt;br /&gt;An acccessible metamodel that is at least as capable as that in LINQ to SQL (i.e. &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.metamodel.aspx"&gt;MetaMode&lt;/a&gt;l and friends). On my current project the metamodel has saved us over and over again - allowing us to &lt;a href="http://dotnet.agilekiwi.com/blog/2008/11/linq-to-sql-presentation.html"&gt;do things that we needed&lt;/a&gt; but couldn't do with just the basic generated entities. I think it's extremely important to have this kind of "back door" that lets programmers step outside of the POCO model and access mapping-related state and metadata.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Lifecyle information in constructor&lt;/b&gt;&lt;br /&gt;A way to tell the difference between explicit construction of an object in code, verus construction by EF as the object is loaded out of the database. This is a gap that we've seen in LINQ to SQL. There are partial methods for various parts of the object lifecyle (such as creation and pre-save validation) but there is no way to tell whether the creation event is happening due to a load from the database, or the "new"-ing of an instance by application code. It seems wrong to have a full set of "hooks" into the object lifecycle &lt;i&gt;except&lt;/i&gt; for this. &lt;br /&gt;My suggestion would be to have the generated entity class include two constructors. One would be a parameterised constructor. Its parameter would be an enum that indicates whether creation is due to loading or some other reason. E.g. &lt;br /&gt;public Person(CreationContext context)&lt;br /&gt;{.. } &lt;br /&gt;where context may be something CreationContext.NewInstance or CreationContext.Loading&lt;br /&gt;The other generated constructor would simply look like this&lt;br /&gt;public Person():this(CreationContext.NewInstance)&lt;br /&gt;{...}&lt;br /&gt;So, when we write "new Person()" in code, the parameterless constructor passes the NewInstance parameter through to the "real" constructor. When the framework loads an object from the database, it should call the parameterized constructor directly, passing CreationContext.Loading. Then, at construction time, the object can always tell the purpose for which it is being constructed: does it represent a brand-new entity, or is it, conceptually, an existing entity which is being "deserialized" from the database?&lt;br /&gt;The most obvious use for this is objects which, when created, should always have particular child objects. &lt;a href="http://social.msdn.microsoft.com/forums/en-US/linqtosql/thread/ed497bcc-0d3c-4de8-8f7b-fe432e8f258e/"&gt;E.g. an order that always has at least one order line&lt;/a&gt;. If the order doesn't know why it's constructor has been called, then it cannot go ahead and make a default child instance - one might already exist in the database in the CreationContext.Loading scenario.&lt;br /&gt;&lt;b&gt;3. Don't presume or require a big impedance mismatch&lt;/b&gt;&lt;br /&gt;There are some advantages to LINQ to SQL's very direct mapping approach. In particular, because the database is virtually identical to the object model the team only has to learn, understand and remember &lt;i&gt;one&lt;/i&gt; model. The means that &lt;a href="http://jamesshore.com/Agile-Book/ubiquitous_language.html"&gt;Ubiquitous Language&lt;/a&gt; extends all the way down to the database. (Particularly important if SQL, rather than objects, will be the basis for report generation; but still useful even if you're not doing SQL reporting, IMHO.)&lt;br /&gt;As soon as you get the complex mappings, which are touted as an advantage of EF, the team has to understand &lt;i&gt;two&lt;/i&gt; models, &lt;i&gt;and&lt;/i&gt; the relationship between them. &lt;br /&gt;In some applications, such mapping is indeed necessary. Perhaps an existing database doesn't match good object design; or the object design is complex enough to require non-trival mappings. &lt;br /&gt;However, in projects where the same team is building the application and database from scratch, and where the object model is not too complex, it can be a good thing to have a simple mapping that's virtually one-to-one. EF should allow this, and the EF documentation should present it as a valid option. &lt;br /&gt;&lt;b&gt;4. Hand-writable entities&lt;/b&gt;&lt;br /&gt;Property getters and setters, on domain entities, should be simple enough to write by hand. This can be done by some kind of AOP (to inject "smarts" into ordinary-looking properties) or by &lt;a href="http://www.codeplex.com/ActiveSharp"&gt;ActiveSharp&lt;/a&gt;. LightSpeed is a good example of an ORM in which all the "smarts" of property setting and getting reside behind &lt;a href="http://www.mindscape.co.nz/blog/?p=64"&gt;simple hand-writable properties&lt;/a&gt;. &lt;br /&gt;[Disclaimer: I wrote ActiveSharp and Lighspeed (optionally) uses it. My point here is not to promote my own code, but to promote the idea that entity properties should be concise. Concise properties, whether hand-written or codegen'd, make the code much easier to work with.]&lt;br /&gt;&lt;b&gt;5. Object relationships should be able to span diagrams (and assemblies)&lt;/b&gt;&lt;br /&gt;An annoying limitation of LINQ to SQL (&lt;a href="http://www.thedatafarm.com/blog/CommentView,guid,d3e59302-828b-4c02-ba89-9a1916465529.aspx"&gt;and LINQ to Entities&lt;/a&gt;) is that, in practice, all your entities must be in one designer diagram. I say that because, if they are not in one diagram, then you can't have meaningful relationships (and lazy loading) between objects in different diagrams. &lt;br /&gt;This relates to point 4, above. If properties are simple enough to write by hand, then you can use several different diagrams and then "stitch them together" using hand-coded relationship properties.&lt;br /&gt;E.g. you might have one diagram focusing on enties related to sales, and another on entities related to production. For the (hopefully few) relationships that go from entities in the Sales diagram to entities in the Production diagram, you can create them by hand as long as hand-authoring is a viable option.&lt;br /&gt;I'm planning to do this on my current LINQ to SQL project, possibly using some of &lt;a href="http://www.codeplex.com/Close2Poco"&gt;this&lt;/a&gt; code.&lt;br /&gt;Finally, such a solution should not just allow entities to be defined on different diagrams, but also for those diagrams (and their generated entities) to be in different assemblies/projects.&lt;br /&gt;Well, that's the end of my 2c worth.... for now ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-5164363880808405326?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2009/01/things-id-like-to-see-in-entity.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-6810272598705132144</guid><pubDate>Tue, 02 Dec 2008 08:19:00 +0000</pubDate><atom:updated>2010-04-27T01:19:46.698-07:00</atom:updated><title>What's up with P&amp;P?</title><description>What's up with the interface between Microsoft's Patterns and Practices group (P&amp;amp;P) and the wider community?&lt;br /&gt;&lt;br /&gt;P&amp;amp;P are writing a new version of their guidance for architecture on the Microsoft platform, and they're asking for community feedback.  But by and large the community isn't giving any!  And, when feedback is offered, P&amp;amp;P aren't necessarily replying.  &lt;br /&gt;&lt;br /&gt;For instance: &lt;br /&gt;&lt;br /&gt;After the P&amp;amp;P Knowledge base project had been up for about 2 months, I &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/09/11/p-amp-p-architectural-guidance-version-2.aspx#184256"&gt;counted&lt;/a&gt; exactly &lt;span style="font-style: italic;"&gt;three&lt;/span&gt; meaningul comments on the substance of what MS had written.  Of those three comments, two were from me(!), and to this day those two &lt;a href="http://www.codeplex.com/AppArch/Thread/View.aspx?ThreadId=39113"&gt;remain unanswered&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Confusingly, there are now three different CodePlex projects in which P&amp;amp;P are seeking community input.  There's the &lt;a href="http://www.codeplex.com/AppArch"&gt;App Arch Guide knowledge base&lt;/a&gt;, the &lt;a href="http://www.codeplex.com/AppArchGuide"&gt;App Arch Guide Book&lt;/a&gt;, and the &lt;a href="http://www.codeplex.com/AppArchContrib"&gt;App Arch Community Contribution project&lt;/a&gt; (which, as if to prove my point, is completely empty)!&lt;br /&gt;&lt;br /&gt;So, community, &lt;span style="font-style: italic;"&gt;what's up!&lt;/span&gt; Has no-one got &lt;span style="font-style: italic;"&gt;anything&lt;/span&gt; to say about architecture!!!!&lt;br /&gt;&lt;br /&gt;And Microsoft, what's up with you?  What are you doing to make this work?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Update 1 Feb 08:&lt;/span&gt; Microsoft recently contacted me to follow up on my questions.  Thanks :-)  As much as I appreciate that contact (and I do) the overall lack of engagement seems to remain.  I still don't see much meaningful involvement from/with the community.  The &lt;a href="http://www.codeplex.com/AppArchContrib"&gt;Community Contribution project&lt;/a&gt; is still empty, except for a brief statement of it's purpose, which has only been &lt;span style="font-style: italic;"&gt;read&lt;/span&gt; 38 times.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-6810272598705132144?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/12/whats-up-with-p.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3253940569594423776</guid><pubDate>Wed, 19 Nov 2008 06:48:00 +0000</pubDate><atom:updated>2010-04-27T01:19:41.219-07:00</atom:updated><title>Hosting a window from one process inside another</title><description>Every time this topic comes up, I seem to have lost my bookmarks on it. So, here's a blog entry so I won't lose them again...&lt;br /&gt;&lt;br /&gt;Under Windows it is possible to visually "dock" the main window of one process inside a Window belonging to another process.  You get the visual effect of one program, but there are still two completely separate exes involved.&lt;br /&gt;&lt;br /&gt;I once used this to "host" an EXE inside Internet Explorer.  We wrote a little tiny ActiveX (this was in the dark ages before managed code). All the ActiveX did was start our EXE, and then "dock" the EXE's main window inside the client area of the ActiveX.  It &lt;span style="font-style: italic;"&gt;looked&lt;/span&gt; like our EXE &lt;span style="font-style: italic;"&gt;was&lt;/span&gt; the ActiveX - but our EXE had no idea that any of this was going on.  It just doing its thing, running as an independent process.&lt;br /&gt;&lt;br /&gt;The secret is the Windows API function SetParent. You can use it to set a window from process A as the parent of the main window of process B.&lt;br /&gt;&lt;br /&gt;I haven't done this for a while.  As I recall you need to make another call to make the hosted window look like a borderless child window (SetWindowLong IIRC) and I think I also had to detect resising of the "host" and programatically resize the child.&lt;br /&gt;&lt;br /&gt;Here are some links on the subject, following a rather brief Google:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geekswithblogs.net/gyoung/archive/2006/04/26/76521.aspx"&gt;http://geekswithblogs.net/gyoung/archive/2006/04/26/76521.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeguru.com/forum/showthread.php?threadid=234862"&gt;http://www.codeguru.com/forum/showthread.php?threadid=234862&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/miscctrl/winwordcontrol.aspx"&gt;http://www.codeproject.com/KB/miscctrl/winwordcontrol.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm fairly sure I learnt this technique from something on Microsoft's site, in about 2000.  But &lt;a href="http://blogs.msdn.com/johnrdurant/archive/2006/01/23/host-word-winform.aspx"&gt;this post&lt;/a&gt; says they are no longer recommending it (at least, not for hosting Office apps) so perhaps that explains why I can't find the original MS post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3253940569594423776?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/11/hosting-window-from-one-process-inside.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-4072771872732786301</guid><pubDate>Tue, 04 Nov 2008 07:51:00 +0000</pubDate><atom:updated>2010-04-27T01:19:36.183-07:00</atom:updated><title>LINQ to SQL Presentation</title><description>Here is a copy of the presentation I have at the 2008 Christchurch Code Camp. (&lt;a href="http://dotnet.agilekiwi.com/LinqToSql-JohnRusk.ppt.zip"&gt;zipped ppt&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;One of the key points of the presentation was to cover what LINQ to SQL includes, both out-of-the-box, and with the additions that we have been able to build on top of it at &lt;a href="http://www.optimation.co.nz/"&gt;Optimation&lt;/a&gt;. I put together the list that follows from two sources: Ayende's list of &lt;a href="http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx"&gt;25 things your OR Mapper must do&lt;/a&gt;; plus other things that we found useful. Ayende's points are in normal font; my additions to his is are shown in italics.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Out of the box, you get:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;CRUD and querying&lt;br /&gt;Transactions&lt;br /&gt;(Bi-directional) associations&lt;br /&gt;Lazy loading&lt;br /&gt;Polymorphic queries (single-table inheritance only)&lt;br /&gt;"Dirty Tracking" with ability to return full change set&lt;br /&gt;Loading properties without loading whole object&lt;br /&gt;Identity Map&lt;br /&gt;Concurrency Control&lt;br /&gt;Acceptable debuggability&lt;br /&gt;Safe multi-threading (1 datacontext = 1 user on 1 thread is the general rule of thumb)&lt;br /&gt;Well-defined exception policy&lt;br /&gt;Lifecycle events (create/update etc)&lt;br /&gt;Composite primary keys&lt;br /&gt;Automatic dependency ordering when saving changes&lt;br /&gt;Paging support (via Skip/Take)&lt;br /&gt;Aggregation support (group/max/min etc)&lt;br /&gt;&lt;i&gt;Original value tracking&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Property change notifications&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Runtime SQL logging&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Ability to generate database from object model&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Persistence by reachabilty&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Enhanced "reflection" via LINQ to SQL MetaModel&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;With our add-ons to LINQ to SQL you (or at least we ;-) also get&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Undo (both to "as fetched" and "current DB state")&lt;br /&gt;Flexible eager load&lt;br /&gt;&lt;i&gt;Unit testability&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Test: is this object new?&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Check mapping against DB&lt;/i&gt;&lt;br /&gt;&lt;i&gt;In-memory savepoints (like DB savepoints, but for in-memory entities which haven't been saved yet)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Proper serialization of entities (none of the usual LINQ to SQL serialization restrictions)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Clone trees of related entities (clone parent with children)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Delete-any-object (even if is a new unsaved one; automatically sever relationships to other objects)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Get data context from object (based on &lt;/i&gt;&lt;a href="http://www.lowendahl.net/showShout.aspx?id=185"&gt;&lt;i&gt;this&lt;/i&gt;&lt;/a&gt;&lt;i&gt; with only very minor changes)&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Get reachable objects (approximates "find me all objects in the datacontext)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;You get only limited support for:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Caching at unit-of-work (datacontext) level&lt;br /&gt;Custom field types (limited to built-in types, enums, xml, .Parse()-able strings and binary ISerializable. &lt;a href="http://msdn.microsoft.com/en-us/bb386947.aspx"&gt;Here&lt;/a&gt; is the valuable and hard-to-find reference page)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;You get no support at all for:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Caching at application-wide level (other than that which is done for you by SQL Server itself)&lt;br /&gt;Cache invalidation policies&lt;br /&gt;Update batching&lt;br /&gt;Cascading update/delete in object model (must rely on DB to do this instead, if you want it)&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;br /&gt;All in all, its a fairly strong list. Stronger, I suspect, than many people expect.&lt;br /&gt;&lt;br /&gt;As for the rest of the presentation, some of it will make sense from written slides, and some won't ;-) A couple of notes here might help:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The solution to comments on entity properties, and refreshing the designer, can be found &lt;a href="http://blog.huagati.com/res/index.php/cat/tools/"&gt;here&lt;/a&gt;. It looks real good, although I haven't got round to trying it yet myself.&lt;/li&gt;&lt;li&gt;Here are the hyperlinks to the &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=343378"&gt;change set&lt;/a&gt; and &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=376669"&gt;association bugs&lt;/a&gt;. NOTE: Microsoft have just announced that they will fix the latter in .NET 4.0, which goes to prove that they really are going to include LINQ to SQL fixes in that release.&lt;/li&gt;&lt;li&gt;&lt;br /&gt;Using the "mapping checker" code. These three points will help if you want to use it: LinqUtil.GetModel is our wrapper for MappingSource.GetModel() - see later slides for details; LinqUtil.IsMappedType() is our wrapper for calling IsEntity on a metaType returned from the MetaModel; and Uow.All(type) is our wrapper for DataContext.GetTable(type). Simply copy the code, replacing our wrappers as noted above.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;That's all for now. As noted in the presentation, please do comment below or email me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-4072771872732786301?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/11/linq-to-sql-presentation.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-1829171684730202341</guid><pubDate>Sun, 02 Nov 2008 08:21:00 +0000</pubDate><atom:updated>2010-04-27T01:19:30.724-07:00</atom:updated><title>Future of LINQ to SQL</title><description>Yesterday, I did a presentation on LINQ to SQL.  &amp;nbsp;At about the time I was talking about how great it was, Microsoft was announcing that LINQ to SQL will not be their recommended solution in .NET 4! &amp;nbsp;They will be recommending LINQ to Entities instead.&lt;br /&gt;Here, in no particular order, are some intial thoughts:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Sorry I wasn't well-informed enough to mention this at the presentation! &amp;nbsp;It seems like the news hit the net after I left for the Code Camp. &amp;nbsp;I did hear there'd been speculation from outside Microsoft, but I mistakenly dismissed it as an over-reaction to the recent emphasis on Entity Framework.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The news is not as bad as it sounds. &amp;nbsp;The best post on the topic seems to be this one: &lt;a href="http://damieng.com/blog/2008/10/31/linq-to-sql-next-steps"&gt;http://damieng.com/blog/2008/10/31/linq-to-sql-next-steps&lt;/a&gt;. &amp;nbsp;&lt;i&gt;Read that post now, if you have not done so already.&lt;/i&gt; &amp;nbsp;Basically, LINQ to SQL will still be available and there will even be improvements and bug fixes. &amp;nbsp;In particular "we [Microsoft] are going to make sure LINQ to SQL continues to operate as it should. This doesn’t just mean making sure what we had works in .NET 4.0 but also fixing a number of issues that have arisen as people pick it up for more advanced projects and put it into production environments".&lt;/li&gt;&lt;li&gt;To successfully execute this strategy, Microsoft will have to bring the best of LINQ to SQL to LINQ to Entities - in particular, they will have to bring lightness, speed and simplicity to cases where the mapping is simple and relatively direct. &amp;nbsp;I hope the &lt;a href="http://andrewpeters.net/2008/09/02/joining-microsoft/"&gt;recent addition of Andrew Peters&lt;/a&gt; to the team will help in that regard, due to his experience on Mindscapes' &lt;a href="http://www.mindscape.co.nz/products/LightSpeed/default.aspx"&gt;LightSpeed&lt;/a&gt; ORM.&amp;nbsp; &amp;nbsp;&lt;/li&gt;&lt;li&gt;I think it will be very important for LINQ to Entities to expose the equivalent of LINQ's MetaModel - complete with the ability to use it to implement workarounds, as I demonstrated in my presentation. &amp;nbsp;(We use the MetaAccessors to do all kinds of things). We've been able to use it plug virtually all the "holes" we've found in LINQ to SQL, and a similar capability is a must in LINQ to Entities if it is to become the favoured product.&lt;/li&gt;&lt;li&gt;Microsoft: to make this kind of announcement, about a product that has been out for less than 12 months, is not a good look! &amp;nbsp;(LINQ to SQL's production release was roughtly 11 months ago). &amp;nbsp;This is particularly true in the area of data access, where there were already plenty of jokes about a long history of technical changes - &lt;a href="http://www.joelonsoftware.com/articles/fog0000000339.html"&gt;ODBC, RDO, DAO, ADO, OLEDB, now ADO.NET.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;For projects you start today, with .NET 3.5, I believe the advice I gave in the presentation is still accurate. &amp;nbsp;For simple mapping consider products like LINQ to SQL and LightSpeed; for complex mapping consider products like LINQ to Entities and nHibernate. &amp;nbsp;&amp;nbsp;&lt;i&gt;If&lt;/i&gt; Microsoft achieves the goals mentioned above, my advice &lt;i&gt;might&lt;/i&gt; change for &lt;i&gt;new &lt;/i&gt;projects that are started after .NET 4 is released.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-1829171684730202341?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/11/future-of-linq-to-sql.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3747430092097230603</guid><pubDate>Tue, 21 Oct 2008 08:13:00 +0000</pubDate><atom:updated>2010-04-27T01:19:25.300-07:00</atom:updated><title>Presenting at Christchurch Code Camp 2008</title><description>I'm presenting at the &lt;a href="http://dot.net.nz/Default.aspx?tabid=119"&gt;Christchurch Code Camp&lt;/a&gt; on 1 November.&lt;br /&gt;&lt;br /&gt;I'm presenting on LINQ-to-SQL and also on my open source project, &lt;a href="http://www.codeplex.com/ActiveSharp"&gt;ActiveSharp&lt;/a&gt;.  If &lt;i&gt;you &lt;/i&gt;were coming to a presentation on either of those topics, what would you like to hear?  (This is your chance to shape the presentations, because I haven't finished writing them yet ;-)&lt;br /&gt;&lt;br /&gt;At the moment, the abstracts for the two presentations look like this:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Title: &lt;/b&gt;Extending LINQ to SQL&lt;br /&gt;&lt;br /&gt;Abstract: How to build on LINQ to SQL to add extra capabilities and work around the product’s limitations.  The presentation will share techniques we’ve used at Optimation to "push the envelope" when using LINQ to SQL.  I’ll outline the base techniques, how we’ve applied them, and the minor limitations that remain unresolved. For those new to LINQ to SQL, the presentation will begin with a whirlwind introduction to the product.  It will conclude with some thoughts on how LINQ fits into the "big picture" of .NET ORM tools.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;and &lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Title:&lt;/b&gt; Low-Level .NET – a look at ActiveSharp&lt;br /&gt;&lt;br /&gt;Abstract: How to get started on working with MSIL, the low-level "assembly" language for .NET.  The presentation is based on my experiences writing ActiveSharp, a library which parses MSIL at runtime and also emits its own runtime-generated methods.  I’ll introduce the key concepts, cover some techniques to help you "cheat" while you learn, and include examples from the ActiveSharp codebase.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;What do you think?  Am I focusing on the right points?  Are there other aspects of these subjects which you'd prefer me to cover instead?  All suggestions welcome...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3747430092097230603?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/10/presenting-at-christchurch-code-camp.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3039149428774094370</guid><pubDate>Sat, 04 Oct 2008 22:44:00 +0000</pubDate><atom:updated>2010-04-27T01:19:20.152-07:00</atom:updated><title>How eBoostr Works</title><description>I'm &lt;a href="http://dotnet.agilekiwi.com/blog/2008/09/visual-studio-performance-with-slow.html"&gt;using eBoostr&lt;/a&gt; to speed up compile times in Visual Studio.&lt;br /&gt;&lt;br /&gt;My only complaint with the product was the lack of documentation on what it caches and when. You can view the list of all the files that it is caching, but I couldn't find any documentation on how it actually chooses which files to cache. So, I emailed eBoostr technical support, and they sent back a very helpful and informative reply - which they kindly allowed me to quote in this post.&lt;br /&gt;&lt;br /&gt;eBoostr works as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It monitors all read/write requests to the hard disk, and gathers statistics on the most frequently-read files&lt;/li&gt;&lt;li&gt;By default it will "update cache contents each hour during computer idle time automatically". You can also manually request a cache rebuild (if your computer has no idle time(!), or you just want the cache to reflect your most recent usage patterns).&lt;/li&gt;&lt;li&gt;It doesn't mess with write operations. Each write goes straight to the real disk. If the file was cached, the cached copy is invalidated. The cached copy will not become valid again until the next cache rebuild.&lt;/li&gt;&lt;li&gt;If you are using both RAM and USB caching, RAM "has the highest priority" (so gets the most frequently used files, I presume). Files in RAM are not cached on USB.&lt;/li&gt;&lt;/ol&gt;At first, the algorithm struck me as a little crude. But on reflection I realised that it makes sense. By rebuilding the cache in batch mode (either automatically or manually) eBooster can make sure that the cache reflects the most commonly-used files. Contrast that with the other approach, which would be to move a file into the cache as soon as it is read - possibly meaning that an infrequently-read file, which maybe you are only going to read once, will bump a more frequently-used file out of the cache.&lt;br /&gt;&lt;br /&gt;Subjectively, eBoostr seems to be working well for me. And as I've &lt;a href="http://dotnet.agilekiwi.com/blog/2008/09/visual-studio-performance-with-slow.html"&gt;mentioned previously&lt;/a&gt;, it seems to be getting very high cache hit ratios in my typical daily usage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3039149428774094370?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/10/how-eboostr-works.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-8699053366690186926</guid><pubDate>Mon, 15 Sep 2008 08:15:00 +0000</pubDate><atom:updated>2010-04-27T01:19:14.633-07:00</atom:updated><title>Visual Studio Performance with Slow Laptop Drives</title><description>As &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx"&gt;Scott Guthrie wrote&lt;/a&gt;, hard drive speed makes a big difference to the performance of Visual Studio.&lt;br /&gt;&lt;br /&gt;So what can you do if, like me, you are using a laptop and so can't upgrade to a faster hard-drive? I've found two things that have helped a &lt;span style="font-style: italic;"&gt;lot&lt;/span&gt;. In one test case they reduced my build time from 28 seconds down to 3 seconds(*).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1: Avoid slow virus scanners&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This made the biggest difference of all. As &lt;a href="http://www.codinghorror.com/blog/archives/000803.html"&gt;Jeff Atwood reports&lt;/a&gt;, some real-time anti-virus scanners can slow your machine down drastically. My test build dropped from 28 seconds to 7 seconds when I turned off my virus scanner! That seems entirely consistent with the results that Jeff has summarised on his page. In fact, judging by his post, it appears that some products may be even worse.&lt;br /&gt;&lt;br /&gt;For the record, I was using TrendMicro OfficeScan. I don't know why it had such a large adverse impact. Googling the vendor's website failed to unearth anything relevant, but I've heard anecdotal evidence of it reading all bytes in a file when Visual Studio merely wants to check the timestamp. On the other hand, my colleague on the next desk uses the same product (on faster disk hardware) and says it's OK.&lt;br /&gt;&lt;br /&gt;[Update: I've switched to AVG and it's looking good - much, much faster.  I'm also trialing NOD32 on another machine, because I've read good things about it.]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2: Use disk caching (with lots of RAM)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've upgraded to a total of 4GB RAM in my laptop. Since I'm running Windows XP, the operating system only sees &lt;a href="http://members.cox.net/slatteryt/RAM.html"&gt;3-and-a-bit&lt;/a&gt;, but that still gives me enough to run an in-memory disk cache.&lt;br /&gt;&lt;br /&gt;I'm using &lt;a href="http://www.eboostr.com/"&gt;eBoostr&lt;/a&gt; to run the cache. It seems to be working very well. It reduced my test build from 7 seconds down to 3 seconds, and subjectively it seems to be having a noticable positive influence*.&lt;br /&gt;&lt;br /&gt;If you go to the eBoostr site, you'll see that it is advertised as being the XP equivalent of two Vista technologies, ReadyBoost and SuperFetch. Those technologies are about reducing system boot and application start times, but it also turns out to be good at reducing &lt;span style="font-style: italic;"&gt;compilation&lt;/span&gt; times. That's not suprising really, since it works by caching the files that are most frequently used. Since I'm interested in compile times rather than boot times, I have configured it to do all it's caching in RAM. I don't even plug in a USB device.&lt;br /&gt;&lt;br /&gt;In a typical day's coding its built-in monitoring tool reports average cache hit ratios of around 80 or 90%, which means it's allowing the machine to skip a &lt;span style="font-style: italic;"&gt;lot&lt;/span&gt; of disk access.&lt;br /&gt;&lt;br /&gt;I definetely recommend giving eBoostr a try. The cost is very competitive and it has very generous evaluation terms - you can use the eval copy for ever, with the only limitation being that it turns itself off 4 hours after every reboot. This means you can take your time evaluating it, as long as you don't mind rebooting daily.&lt;br /&gt;&lt;br /&gt;My only criticism would be that the documentation doesn't really explain how it decides which files to cache. I emailed the vendor about that point, and they sent a very informative reply, which I'll summarise in a future post [&lt;a href="http://dotnet.agilekiwi.com/blog/2008/10/how-eboostr-works.html"&gt;here&lt;/a&gt;].&lt;br /&gt;&lt;br /&gt;One word of advice: if you run Visual Studio and a local copy of SQL Server (as I do), don't bother with RAM caching if you only have 2GB of RAM. Get more RAM first, then start caching. I'm using a cache size of about 800MB, which seems large enough to be useful, and small enough to leave enough RAM for all my dev tools.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Finally...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(*) Your mileage may vary - and in fact my mileage does too, depending on what I'm doing and (presumably) on what is in the cache at the time. In some of my tests, the virus scanner seems to account for all the difference; with little difference coming from the cache. In other tests, the cache makes a noticable difference.&lt;br /&gt;&lt;br /&gt;In any case, I'm enjoying TDD again. The 30-second builds used to break my chain of thought, but now the edit-compile-test cycle is short enough that it doesn't interrupt my &lt;a href="http://en.wikipedia.org/wiki/Flow_(psychology)"&gt;flow&lt;/a&gt;. All in all, my 5400 RPM drive no longer feels like a serious problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-8699053366690186926?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/09/visual-studio-performance-with-slow.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-4242940424578390389</guid><pubDate>Sat, 30 Aug 2008 21:01:00 +0000</pubDate><atom:updated>2010-04-27T01:19:09.340-07:00</atom:updated><title>Syntactic Noise sample in C#</title><description>Martin Fowler wrote an interesting post on &lt;a href="http://martinfowler.com/bliki/SyntacticNoise.html"&gt;syntactic noise in internal DSLs&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I thought it would be interesting to compare the Java versions (there are two in his post) with a concise C# version. Here is the result, the most concise C# version that I could come up with:&lt;br /&gt;&lt;span style="color: red;"&gt;static&lt;/span&gt; &lt;span style="color: red;"&gt;Event&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DoorClosed &lt;span style="color: red;"&gt;= "&lt;/span&gt;D1CL&lt;span style="color: red;"&gt;",&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DrawOpened &lt;span style="color: red;"&gt;= "&lt;/span&gt;D2OP&lt;span style="color: red;"&gt;", &lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LightOn &lt;span style="color: red;"&gt;= "&lt;/span&gt;L1ON&lt;span style="color: red;"&gt;";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;static  Command&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LockPanel &lt;span style="color: red;"&gt;= "&lt;/span&gt;PNLK&lt;span style="color: red;"&gt;",&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UnlockDoor &lt;span style="color: red;"&gt;= "&lt;/span&gt;D1UL&lt;span style="color: red;"&gt;";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;static&lt;/span&gt; &lt;span style="color: red;"&gt;State&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Idle &lt;span style="color: red;"&gt;= new State&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UnlockDoor&lt;span style="color: red;"&gt;, &lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LockPanel&lt;span style="color: red;"&gt;,&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DoorClosed&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;Active&lt;span style="color: red;"&gt;)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: red;"&gt;},&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Active &lt;span style="color: red;"&gt;= new State&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: red;"&gt;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DrawOpened&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;WaitingForLight&lt;span style="color: red;"&gt;),&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LightOn&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;WaitingForDraw&lt;span style="color: red;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's reasonably concise (slightly more so that the fluent Java one I think), however it did require me to make everything static - which kind of counts as cheating ;-) &lt;b&gt;[Update 9 Sept:]&lt;/b&gt; So here is a more realistic version:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;public Event&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;DoorClosed &lt;span style="color: red;"&gt;= "&lt;/span&gt;D1CL&lt;span style="color: red;"&gt;",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;DrawOpened &lt;span style="color: red;"&gt;= "&lt;/span&gt;D2OP&lt;span style="color: red;"&gt;",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;LightOn &lt;span style="color: red;"&gt;= "&lt;/span&gt;L1ON&lt;span style="color: red;"&gt;";&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;public Command&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;LockPanel &lt;span style="color: red;"&gt;= "&lt;/span&gt;PNLK&lt;span style="color: red;"&gt;",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;UnlockDoor &lt;span style="color: red;"&gt;= "&lt;/span&gt;D1UL&lt;span style="color: red;"&gt;";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;public State&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Idle&lt;span style="color: red;"&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Active&lt;span style="color: red;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;protected void Setup()&lt;br /&gt;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: red;"&gt;Idle &lt;/span&gt;&lt;span style="color: red;"&gt;= new State&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UnlockDoor,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LockPanel,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DoorClosed&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;Active&lt;span style="color: red;"&gt;)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: red;"&gt;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Active &lt;/span&gt;&lt;span style="color: red;"&gt;= new State&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DrawOpened&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;WaitingForLight&lt;span style="color: red;"&gt;), &lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LightOn&lt;span style="color: red;"&gt;.TransitionTo(&lt;/span&gt;WaitingForDraw&lt;span style="color: red;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;};&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The key differences from the Java version are that it uses implicit conversions to convert strings directly to Events and Commands, and that it uses collection initializers to set up the contents of the States. (Note that a collection initializer need not contain things that are all of the same type. Instead, it will accept all types for which the target collection has an Add method. In our case, that is Commands and Transitions (created by TransitionTo)).&lt;br /&gt;&lt;br /&gt;Full &lt;a href="http://www.agilekiwi.com/dotnet/SyntacticNoiseCSharpSample.cs"&gt;source code&lt;/a&gt; is attached.&lt;br /&gt;&lt;br /&gt;PS as I've noted &lt;a href="http://dotnet.agilekiwi.com/blog/2006/10/shorthand-interfaces.html"&gt;before&lt;/a&gt;, I think that C# offers more options for in-language DSL syntax than Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-4242940424578390389?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/08/syntactic-noise-sample-in-c.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-8783795275666879832</guid><pubDate>Tue, 26 Aug 2008 08:14:00 +0000</pubDate><atom:updated>2010-04-27T01:19:04.150-07:00</atom:updated><title>A Practical Step in the Stored Proc Debate</title><description>I've taken a practical step in the long-running debate for and against stored procs.&lt;br /&gt;&lt;br /&gt;I've logged a &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=357997"&gt;formal suggestion&lt;/a&gt; with Microsoft asking them to correct their erroneous advice on the subject. :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms978510.aspx"&gt;This&lt;/a&gt; Patterns and Practices page says:&lt;br /&gt;&lt;blockquote&gt;Stored procedures generally result in improved performance because the database can optimize the data access plan used by the procedure and cache it for subsequent reuse.&lt;/blockquote&gt;&lt;br /&gt;That's been factually incorrect for the last decade! In terms of query plan caching, Parameterized SQL and Stored Procs are &lt;a href="http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx"&gt;handled in the same way&lt;/a&gt; - and they have been since SQL Server 7. &lt;br /&gt;&lt;br /&gt;So, if you too are disappointed by the level of erroneous information in this &lt;a href="http://weblogs.asp.net/fbouma/archive/2006/05/26/Yay_2100_-A-new-Stored-Proc-vs.-Dyn.-Sql-battle_2100_.aspx"&gt;long running&lt;/a&gt; debate, head over to the &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=357997"&gt;feedback page&lt;/a&gt; and support my request to fix the P&amp;amp;P page. You can support it via commenting on the page or by using the Validation link at the top. &lt;br /&gt;&lt;br /&gt;Let's hope we can get the page corrected, and achieve a small step for rationality in an often irrational debate :-)&lt;br /&gt;&lt;br /&gt;(Apologies to Microsoft if my tone sounds hash. I know you've already got the correct information up on other parts of your site.)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update Oct 08:&lt;/b&gt; the P&amp;amp;P guidance &lt;a href="http://blogs.msdn.com/jmeier/archive/2008/09/02/patterns-practices-app-arch-guide-2-0-project.aspx"&gt;is being updated&lt;/a&gt;, so one presumes this will be fixed as part of that work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-8783795275666879832?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/08/practical-step-in-stored-proc-debate.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-4621056278700105749</guid><pubDate>Fri, 18 Jul 2008 09:11:00 +0000</pubDate><atom:updated>2010-04-27T01:18:59.267-07:00</atom:updated><title>Software Development Meme</title><description>I've been tagged by &lt;a href="http://andrewpeters.net/2008/07/11/when-memes-attack/"&gt;Andrew&lt;/a&gt;, in a software development &lt;a href="http://thedailymeme.com/what-is-a-meme/"&gt;meme&lt;/a&gt; that started way back &lt;a href="http://www.michaeleatonconsulting.com/blog/archive/2008/06/04/how-did-you-get-started-in-software-development.aspx"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How old were you when you started programming?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was exactly 13.  My parents bought me my first computer for my 13th birthday.  It was a second-hand &lt;a href="http://www.technology.niagarac.on.ca/staff/mcsele/OhioScientific.html"&gt;Ohio Scientific Superboard II&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;By the way, the Superboard shipped in 1978 as a single circuit board.  It had keys mounted on the front and chips mounted on the back.  That’s it.  No case, no nothing – just one big circuit board with stuff on it.  By the time it reached me a few years later, mine had been fitted into a hand-built wooden case, and its memory had been expanded to 16&lt;span style="font-style: italic;"&gt;k&lt;/span&gt;.  (I still have the machine.  If anyone knows how to fix a Superboard II that won’t respond to the Break key after power-up, please &lt;a href="http://www.agilekiwi.com/contact.htm"&gt;contact me&lt;/a&gt; :-)  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How did you get started in programming?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before my SuperBoard, I’d only seen two other computers.  I guess they must have made a big impression on me.  I got Mum and Dad to buy me a book on programming in BASIC, and the purchase of the actual computer followed sometime after.  I don’t recall how much nagging was involved ;-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What was your first language?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Superboard’s version of BASIC, which was &lt;a href="http://blogs.sun.com/Drew/entry/has_anyone_else_heard_of"&gt;apparently&lt;/a&gt; "Microsoft 6502 BASIC version 1.0 revision 3.2".  In hindsight, I love the fact that it was simple enough for a 13 year-old to learn the whole language.  If I recall correctly, there was IF .. THEN, but no ELSE; and GOTO but no GOSUB.  Definitely a minimal language.  It made me appreciate "real" languages when I finally got to use them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What was the first real program you wrote?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It was a clone of the first computer program I’d ever seen – a game where you had to steer a tank through a minefield.  My version had the randomly-generated minefield, and the tank that was stuck on full-throttle while you steered your way though, but it lacked the system-generated comments that poked fun at your crashes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What languages have you used since you started programming?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I’ve done serious development in Pascal, Excel 4.0 Macro language, VBA, Ada, PowerBuilder, PL-SQL, Delphi and C#.  I’ve dabbled in various others including C++, JavaScript and even VB.NET (although it makes my eyes hurt when I read it ;-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What was your first professional programming gig?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I did a few small jobs in BASIC and Excel when I was a student, but my first really serious job was in PowerBuilder for an IT consultancy.  PowerBuilder’s (in)famous DataWindow really was a fast way to get things done.  It set the bar for productivity, and it's only now in 2008 that I feel like we've replicated that speed in .NET - thanks to a good ORM and our in-house framework. (And we get a proper domain model with layering, which we never had in PB!)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If you knew then what you know now, would you have started programming?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yes.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If there is one thing you learned along the way that you would tell new developers, what would it be?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I might tell them that it’s not about technology, it’s really about people – but I don’t think they’d believe me.  &lt;br /&gt;&lt;br /&gt;So instead I’d tell them to read &lt;a href="http://samizdat.mines.edu/howto/HowToBeAProgrammer.html"&gt;How to be a Programmer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What’s the most fun you’ve ever had... programming?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I’ve particularly enjoyed my old Superboard; writing (most of) a compiler at university; doing some funky stuff with COM in Delphi; and releasing &lt;a href="http://www.codeplex.com/ActiveSharp"&gt;a&lt;/a&gt; &lt;a href="http://www.codeplex.com/Close2Poco"&gt;couple&lt;/a&gt; of open source projects.  &lt;br /&gt;&lt;br /&gt;But the thing I look back on most fondly is a .NET project at &lt;a href="http://www.optimation.co.nz/"&gt;Optimation&lt;/a&gt;.  The highlight wasn’t the technology, which was interesting but not amazing; the highlight was the project as a whole.  We had great collaboration with the customer, very much "one team" with great dialogue and innovation, and together we exceeded expectations instead of merely meeting requirements.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Over to you&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nichesoftware.co.nz/"&gt;Bevan&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.smartbeanz.net/blog/"&gt;Eduard&lt;/a&gt;&lt;br /&gt;and&lt;br /&gt;&lt;a href="http://blogs.msdn.com/kirillosenkov/"&gt;Kirill&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-4621056278700105749?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/07/software-development-meme.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-817866053730141821</guid><pubDate>Tue, 15 Jul 2008 10:08:00 +0000</pubDate><atom:updated>2010-04-27T01:18:54.221-07:00</atom:updated><title>POCO LINQ Update</title><description>&lt;a href="http://www.codeplex.com/Close2Poco"&gt;Here &lt;/a&gt;is my &lt;a href="http://dotnet.agilekiwi.com/blog/2007/12/interested-in-poco-linq.html"&gt;long-promised&lt;/a&gt; near-POCO solution for LINQ to SQL.&lt;br /&gt;&lt;br /&gt;As planned, it is deliberately not 100% pure POCO, but it does implement these key goals:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Entity classes are simple enough to be hand-written (no need to generate them with SQL Metal or VS 2008)&lt;/li&gt;&lt;li&gt;Mapping is easy (no need to manually map every property via attributes or external XML)&lt;/li&gt;&lt;li&gt;Lazy-loading works&lt;/li&gt;&lt;li&gt;Bi-directional relationships work (update one end, and the other is synchronized automatically)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-817866053730141821?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/07/poco-linq-update.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-2258890035993646136</guid><pubDate>Sat, 07 Jun 2008 21:20:00 +0000</pubDate><atom:updated>2010-04-27T01:18:48.309-07:00</atom:updated><title>Another reason why architects should write code</title><description>Johanna Rothman explains why &lt;a href="http://www.jrothman.com/weblog/2006/04/architects-must-write-code.html"&gt;architects should write code&lt;/a&gt;.  I completely agree.  &lt;br /&gt;&lt;br /&gt;Not only does hands-on involvement reduce risks on the project, it also reduces embarassment when talking to your kids ;-)  Here's an actual conversation with my daughter:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;What did you do today Dad?&lt;/span&gt;&lt;br /&gt;I drew some diagrams.  Do you know what a diagram is?&lt;br /&gt;&lt;span style="font-style: italic;"&gt;No&lt;/span&gt;&lt;br /&gt;It's a picture that shows how something works.  I drew some diagrams, then I talked with some people about them.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;So you didn't do any work then?&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-2258890035993646136?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/06/another-reason-why-architects-should.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-736508247811786036</guid><pubDate>Wed, 30 Apr 2008 08:51:00 +0000</pubDate><atom:updated>2010-04-27T01:18:40.086-07:00</atom:updated><title>Only 4 New Features in C# vNext?</title><description>I've always admired the effort that Microsoft put into the design of C#.  It's  difficult to find the right balance between power and flexibility, and on the whole I think they've done an excellent job.&lt;br /&gt;&lt;br /&gt;At the same time, it's been great to see the language grow, particularly with the addition of LINQ.  As Jon Skeet has written recently, C# today is noticably more complicated than it was at version 1.0.  Personally, I don't think that's a bad thing. The C# community has grown up along with the langauage, learning the new features as they have been released.&lt;br /&gt;&lt;br /&gt;I can see this process continuing for some time, with the language continuing to grow.  So I was suprised to see this comment from Microsoft's Mads Torgersen, in response to &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=233329"&gt;some&lt;/a&gt; &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278510"&gt;suggestions&lt;/a&gt; that I posted at &lt;a href="http://connect.microsoft.com/"&gt;Microsoft Connect&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;"We have to do some harsh prioritization, both because of our implementation and testing resources, but also because we need to keep the number of new langauge features at a manageable level - depending on how you count, &lt;span style="font-weight: bold;"&gt;we are adding only four language features to C# this time around&lt;/span&gt;".&lt;/blockquote&gt;We more-or-less know that one will be some form of &lt;a href="http://blogs.msdn.com/charlie/archive/2008/01/25/future-focus.aspx"&gt;dynamic lookup&lt;/a&gt;. That just leaves three others.  They might be big "killer" features (like generics and lambda expressions in previous versions) but there's still only &lt;span style="font-style: italic;"&gt;three&lt;/span&gt; of them.&lt;br /&gt;&lt;br /&gt;I don't know what to think. Should we be trilled that Microsoft are continuing their excellent track record of keeping the language simple, or should we be dissapointed that there will be so few improvements?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-736508247811786036?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/04/only-4-new-features-in-c-vnext.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-1766524731146027945</guid><pubDate>Sun, 24 Feb 2008 05:30:00 +0000</pubDate><atom:updated>2010-04-27T01:18:33.188-07:00</atom:updated><title>Summary of C# vNext Ideas in this Blog</title><description>Here's a summary of the ideas I've suggested in this blog, for future versions of C#:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dotnet.agilekiwi.com/blog/2007/11/making-extension-methods-safer.html"&gt;Fix the versioning issues&lt;/a&gt; with extension methods&lt;/li&gt;&lt;li&gt;Consider "&lt;a href="http://kirillosenkov.blogspot.com/2007/11/john-rusk-on-extension-interfaces.html"&gt;extension interfaces&lt;/a&gt;" to provide mixin-like behaviour&lt;/li&gt;&lt;li&gt;Also, consider improving&amp;nbsp;the &lt;a href="http://dotnet.agilekiwi.com/blog/2008/01/resolving-extension-methods.html"&gt;resolving&lt;/a&gt; of extension methods&lt;/li&gt;&lt;li&gt;Retain some means of serializing iterator state (even if the underlying iterator implementation is changed) (See comments &lt;a href="http://dotnet.agilekiwi.com/blog/2007/05/implementing-workflow-with-persistent.html"&gt;here&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Provide an &lt;a href="http://dotnet.agilekiwi.com/blog/2006/06/direct-support-for-symbol-names.html"&gt;infoof&amp;nbsp;operator&lt;/a&gt;,&amp;nbsp;or&amp;nbsp;similar&lt;/li&gt;&lt;li&gt;&lt;a href="http://dotnet.agilekiwi.com/blog/2007/04/quoted-strings.html"&gt;Better handling of @-quoted strings&lt;/a&gt; that contain double quotes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dotnet.agilekiwi.com/blog/2008/02/enhanced-automatic-properties.html"&gt;Enhance automatic properties&lt;/a&gt; to retain their concise syntax but to offer greater flexibility to use programmer-defined code. Particularly helpful for &lt;a href="http://dotnet.agilekiwi.com/blog/2008/02/better-property-change-notification.html"&gt;automatic INotifyPropertyChanged implementation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-1766524731146027945?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/02/summary-of-c-vnext-ideas-in-this-blog.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-7489636117821045320</guid><pubDate>Sun, 24 Feb 2008 04:41:00 +0000</pubDate><atom:updated>2010-04-27T01:18:22.952-07:00</atom:updated><title>Enhanced Automatic Properties</title><description>Recently there's been a lot of blog posts discussing things people would like to see in the next version of C#.  Here's my addition to the wish-list:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Automatic properties that let me supply a method body."&lt;/i&gt;  It sounds like a contradiction in terms - but it doesn't have to be.  Instead, it would be a compact syntax for defining properties that use standardised method bodies (where &lt;span style="font-style: italic;"&gt;you&lt;/span&gt; define your own "standard" bodies).&lt;br /&gt;&lt;br /&gt;Some places where it would be useful:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Cases where  many properties follow a standard format. &amp;nbsp;For instance, all the properties generated by the LINQ designer could be single-line automatic properties. &amp;nbsp;(Much less verbose than the current approach).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ORM's and similar products that require properties to be written according to certain conventions. &amp;nbsp;(E.g. &lt;a href="http://www.mindscape.co.nz/products/LightSpeed/"&gt;Mindscape LightSpeed&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;How would it look?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Right now, we can write automatic properties like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Foo { get; set; }&lt;/pre&gt;My suggestion is that the words "get" and "set" could be replaced by the names of methods.  For instance:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; AdvancedFoo { GetValue; SetValue; }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where the methods "GetValue" and "SetValue" are generic instance methods with these signatures:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// When passed the field, return the property value&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;T GetValue&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;ref&lt;/span&gt; T field)&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;// ... your own code goes here...&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;/// When passed the field, by ref, and the new property value, set the field&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; SetValue&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;ref&lt;/span&gt; T field, T &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="rem"&gt;//...your own code goes here...&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;Given the above property, "AdvancedFoo", the compiler would compile it as if I had written this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; AdvancedFoo&lt;br /&gt;{&lt;br /&gt;get { &lt;span class="kwrd"&gt;return&lt;/span&gt; GetValue(&lt;span class="kwrd"&gt;ref&lt;/span&gt; _advancedFoo); }&lt;br /&gt;set { SetValue( &lt;span class="kwrd"&gt;ref&lt;/span&gt; _advancedFoo, &lt;span class="kwrd"&gt;value&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _advancedFoo; &lt;span class="rem"&gt;// compiler-generated backing field&lt;/span&gt;&lt;/pre&gt;Just as in today's automatic properties, the compiler would generate the backing field for me.  The difference is that it reads and writes that backing field via methods which I define.&lt;br /&gt;&lt;br /&gt;This goes a long way towards giving the best of both worlds: the compact syntax of automatic properties, and the flexibility of my own code (plus standardisation - all me properties that are supposed to work the same way &lt;span style="font-style: italic;"&gt;do&lt;/span&gt; work the same way, because they all use the same code).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Questions:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Why does the "GetValue" method take the field "by ref"?&lt;/span&gt;  SetValue needs it by ref, but why GetValue?  GetValue takes it by ref simply so that you can use &lt;a href="http://dotnet.agilekiwi.com/blog/2008/02/better-property-change-notification.html"&gt;this trick&lt;/a&gt; to find out &lt;span style="font-style: italic;"&gt;which&lt;/span&gt; property is being read - just in case you need to know.  This is something you are more likely to need to know when setting, e.g. to raise change notificiations, but maybe some people want to identify the property in GetValue too.  Using the ref param makes that possible.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;What type should the complier use for the backing field?&lt;/span&gt;  Simply put, it should use whatever field type is implied by the field parameters of the "GetValue" and "SetValue" methods.  E.g. an automatic property for a LINQ EntityRef might look like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;T GetEntity(&lt;span class="kwrd"&gt;ref&lt;/span&gt; EntityRef&amp;lt;T&amp;gt; field) &lt;span class="kwrd"&gt;where&lt;/span&gt; T:&lt;span class="kwrd"&gt;class&lt;/span&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; SetEntity(&lt;span class="kwrd"&gt;ref&lt;/span&gt; EntityRef&amp;lt;T&amp;gt; field, T &lt;span class="kwrd"&gt;value&lt;/span&gt;) &lt;span class="kwrd"&gt;where&lt;/span&gt; T:&lt;span class="kwrd"&gt;class&lt;/span&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;/pre&gt;allowing me to write this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Customer Bar{ GetEntity; SetEntity; }&lt;br /&gt;&lt;/pre&gt;and have the compiler compile it as if I had written this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Customer Bar&lt;br /&gt;{&lt;br /&gt;get { &lt;span class="kwrd"&gt;return&lt;/span&gt; GetEntity(&lt;span class="kwrd"&gt;ref&lt;/span&gt; _bar);}&lt;br /&gt;set { SetEntity(&lt;span class="kwrd"&gt;ref&lt;/span&gt; _bar, &lt;span class="kwrd"&gt;value&lt;/span&gt;);}&lt;br /&gt;}&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; EntitySet&amp;lt;Customer&amp;gt; _bar;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the compiler is able to infer that the backing field should be EntitySet&lt;customer&gt;, not Customer, based on the signatures of Get/SetEntity.&lt;br /&gt;&lt;br /&gt;&lt;small&gt;(And how would Get/SetEntity actually work?  That's a question for another day ;-)  I do have some (working) prototype code...)&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;What do you think of this idea for enhanced automatic properties?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update 2 March:&lt;/span&gt; posted on MS Connect &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278125"&gt;here&lt;/a&gt; (in the comments)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update 12 March:&lt;/span&gt; And here &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=332659"&gt;here&lt;/a&gt; as an MS Connect item in its own right.&lt;/customer&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-7489636117821045320?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/02/enhanced-automatic-properties.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-4950512805883917891</guid><pubDate>Thu, 14 Feb 2008 08:43:00 +0000</pubDate><atom:updated>2010-04-27T01:18:11.463-07:00</atom:updated><title>Extension Methods - Feedback to Microsoft</title><description>If you've been following the disussions about &lt;a href="http://dotnet.agilekiwi.com/blog/2007/11/making-extension-methods-safer.html"&gt;extension methods&lt;/a&gt; in this blog, you might be interested to know that I've submitted the issue to Microsoft's feedback site.  &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=328527"&gt;Jump over there&lt;/a&gt; and vote for it, if you'd like to see something done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-4950512805883917891?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/02/extension-methods-feedback-to-microsoft.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-4877283526663654030</guid><pubDate>Fri, 08 Feb 2008 22:58:00 +0000</pubDate><atom:updated>2010-04-27T01:17:52.869-07:00</atom:updated><title>Better Property Change Notification</title><description>&lt;span style="font-weight: bold;"&gt;aka Automatic INotifyPropertyChanged&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some time ago I developed a new way to do property change notification.  It consists of code which can automatically figure out which property has changed, without you having to tell it.&lt;br /&gt;&lt;br /&gt;Details are &lt;a href="http://dotnet.agilekiwi.com/blog/2007/07/claytons-interception.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've now put together an updated version, and posted it on CodePlex &lt;a href="http://www.codeplex.com/ActiveSharp"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here's how to use the new version:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Option 1:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's the easiest option...&lt;br /&gt;&lt;br /&gt;Add this code to your class or base class:&lt;br /&gt;&lt;pre class="csharpcode"&gt;PropertyChangeHelper _propertyChangeHelper = &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyChangeHelper();&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged&lt;br /&gt;{&lt;br /&gt;add { _propertyChangeHelper.Add(&lt;span class="kwrd"&gt;value&lt;/span&gt;); }&lt;br /&gt;remove { _propertyChangeHelper.Remove(&lt;span class="kwrd"&gt;value&lt;/span&gt;); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetValue&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;ref&lt;/span&gt; T field, T &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;_propertyChangeHelper.SetValue&lt;br /&gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;ref&lt;/span&gt; field, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;Then write your property setter methods like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Foo&lt;br /&gt;{&lt;br /&gt;get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _foo; }&lt;br /&gt;set { SetValue(&lt;span class="kwrd"&gt;ref&lt;/span&gt; _foo, &lt;span class="kwrd"&gt;value&lt;/span&gt;); }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Option 2:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want more control, you can find which property changed like this (and then do whatever you like):&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetValue&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;ref&lt;/span&gt; T field, T &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;...&lt;br /&gt;field = &lt;span class="kwrd"&gt;value&lt;/span&gt;;   &lt;span class="rem"&gt;//Actually assign the new value&lt;/span&gt;&lt;br /&gt;PropertyInfo changedProperty = PropertyMap.GetProperty(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;ref&lt;/span&gt; field);&lt;br /&gt;&lt;span class="rem"&gt;// do whatever you like, now that you know which prop was changed&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;}&lt;/pre&gt;Key differences in the new version are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No "trial sets".  The old version used to call all your property setters, to figure out which fields they corresponded to.  That could be annoying, because you ended up recieving calls to the set methods when your objects were not necessarily ready for them.  The new version doesn't need to do this.  Instead, it inspects the MSIL of the set methods, to figure out what it needs to know.  (The inspection is a one-off runtime operation, so it won't be a performance problem.)&lt;/li&gt;&lt;li&gt;Fewer contraints on how classes are coded.  The old version required that you nominated a special field as the "reference field", to which all others were compared.  The new version does not require that.  Also, the new version lets you use your own base class (with your own SetValue method, named whatever you want).  Fianlly, you can put your own code in the property setter methods (along with the call to your "SetValue" method), something which could cause problems in the old version&lt;/li&gt;&lt;li&gt;Helper class for easy implemetation of property change notifications (as above)&lt;/li&gt;&lt;li&gt;Granualar implementation, so that you can call some of the implmentaiton classes, but still write the outer "layer" of the API yourself if you need to&lt;/li&gt;&lt;li&gt;Lock-free. The new version is threadsafe without explict locks (and without and [ThreadStatic]s). &lt;span style="font-style: italic;"&gt; Update 10 Feb:&lt;/span&gt; This used to rely on a little trick with generics and static fields; but that doesn't play well with inheriance.  It now uses a class I wrote called LazyDictionary, which is basically a dictionary with double-checked locking to ensure that locks are only requested during initialization, and not during the on-going running of the application.  (Didn't want a lock request on every property set call!)&lt;/li&gt;&lt;li&gt;No separate C++ assembly.  The old version used managed C++ to do stuff that C# cannot.  The new version uses reflection emit, to produce the corresponding routine on the fly, so that the separate assembly is not required.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Finally, I have resurrected the name "ActiveSharp" (which I used for a previous, &lt;a href="http://dotnet.agilekiwi.com/blog/2007/06/no-more-development-on-my-side-project.html"&gt;abandonned project&lt;/a&gt;) for this new version of the code.  I did that for two reasons, firstly the new version borrows code from the old ActiveSharp (particulaly the MSIL inspection); and secondly I liked the old name and couldn't think of a better one ;-)  Just like the previous "ActiveSharp", this new version is a product of my &lt;a href="http://en.wikipedia.org/wiki/Micro_ISV"&gt;microISV&lt;/a&gt;, Tasman Logic Ltd.  (The microISV is not exactly a money-making venture, given that its only product is open-source ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-4877283526663654030?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/02/better-property-change-notification.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-3344880181427922176</guid><pubDate>Tue, 15 Jan 2008 07:11:00 +0000</pubDate><atom:updated>2010-04-27T01:17:47.283-07:00</atom:updated><title>Resolving Extension Methods</title><description>Paul Stovell (author of &lt;a href="http://paulstovell.net/blog/index.php/why-synclinq-should-matter-to-you/"&gt;SyncLINQ&lt;/a&gt;) has pointed out another issue with Extension Methods.  As he &lt;a href="http://www.paulstovell.net/blog/index.php/interface-methods-versus-extension-methods#comment-3403"&gt;writes&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The problem is the methods are *resolved* at compile time.&lt;br /&gt;&lt;br /&gt;Suppose you had this:&lt;br /&gt;&lt;br /&gt;void DoStuff(this IFoo foo);&lt;br /&gt;&lt;br /&gt;class FooFactory&lt;br /&gt;IFoo Create()&lt;br /&gt;&lt;br /&gt;If your factory returns an object that provides its own instance implementation of DoStuff, it WILL NOT be invoked - the extension method will instead. This breaks many of the rules around polymorphism and good OO in general...&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;In other words, the compiler &lt;a href="http://dotnet.agilekiwi.com/blog/2006/04/extension-methods-more-than-sugar.html"&gt;favours instance methods over extension methods&lt;/a&gt;, &lt;span style="font-style: italic;"&gt;but only if it can "see" the instance method at compile time&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The reason is simple: currently, resolving an extension method is just a compiler trick, so compile time is the only time when it CAN be done.  &lt;br /&gt;&lt;br /&gt;But Paul's comment got me thinking.  It occured to me that, if my idea about &lt;a href="http://dotnet.agilekiwi.com/blog/2006/04/extension-methods-solution.html"&gt;using interfaces&lt;/a&gt; was implemented, then it would be possible to properly solve the problem he described. It would work like this:&lt;br /&gt;&lt;br /&gt;First, to recap: &lt;a href="http://dotnet.agilekiwi.com/blog/2006/04/extension-methods-solution.html"&gt;I suggest&lt;/a&gt; that there should be a mapping between extension methods and interfaces.  Think of a set of extension methods as an "extension contract".  You can make calls on the methods in that contact either by calling intstance methods (on objects which implement the interface) or by extension methods (for objects which do not implement the interface). This is to solve the &lt;a href="http://dotnet.agilekiwi.com/blog/2006/04/extension-methods-problem.html"&gt;versioning problem&lt;/a&gt;, but it can also be used to solve the problem Paul described.&lt;br /&gt;&lt;br /&gt;How? I'll try to illustrate with an example.  Imagine that our "extension contract" is called IExtensionContract.  It contains two methods, Foo and Bar.  We can call Foo and Bar on objects which &lt;span style="font-style: italic;"&gt;don't&lt;/span&gt; support IExtensionContract, simply by calling them as extesion methods.  But, when we call Foo and Bar on objects which DO support IExtensionContract, we want to call the version that is on the object &lt;i&gt;even if we can't tell that the object supports them at compile time&lt;/i&gt;.  (That's the heart of the issue, right Paul?)&lt;br /&gt;&lt;br /&gt;That could be done if the complier worked like this:&lt;br /&gt;&lt;br /&gt;Given this code to compile&lt;br /&gt;&lt;br /&gt;ISomething s = ...&lt;br /&gt;s.Foo();&lt;br /&gt;&lt;br /&gt;The compiler should compile it as if the programmer had written&lt;br /&gt;&lt;pre class="csharpcode"&gt;ISomething = ...&lt;br /&gt;IExtensionContract c = s &lt;span class="kwrd"&gt;as&lt;/span&gt; IExtensionContract;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt;(c == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;StaticExtender.Foo(s);  &lt;span class="rem"&gt;// invoke the extension method&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;c.Foo();                &lt;span class="rem"&gt;// invoke the instance method&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;This would be possible, if the &lt;a href="http://dotnet.agilekiwi.com/blog/2006/04/extension-methods-solution.html"&gt;interface-based versioning solution&lt;/a&gt; was adopted, because that solution introduces just enough &lt;span style="font-style: italic;"&gt;runtime&lt;/span&gt; information about the extension methods - namely the "contract" to which the methods belong.  Contrast that to the current situation, where there is &lt;span style="font-style: italic;"&gt;no&lt;/span&gt; runtime information about extension methods.&lt;br /&gt;&lt;br /&gt;Here is the user-authored (i.e. not compiler-generated) code for the example above:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; StaticExtender : IExtensionContract &lt;br /&gt;&lt;span class="rem"&gt;// "inheriting" from interface here is my suggested addition to the language&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Foo(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomething s){...}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Bar(&lt;span class="kwrd"&gt;this&lt;/span&gt; ISomething s){...}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IExtensionContract&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Foo();&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Bar();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Finally, all the suggested logic I have blogged about previously still applies. The compiler still needs to decide, at compile time, whether the call is to a method in the extension contract or to a like-named (but otherwise unrelated) instance method.  All that logic still applies as I described it &lt;a href="http://dotnet.agilekiwi.com/blog/2007/11/making-extension-methods-safer.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-3344880181427922176?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/01/resolving-extension-methods.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-24760385.post-2370804097451603149</guid><pubDate>Sun, 13 Jan 2008 00:59:00 +0000</pubDate><atom:updated>2010-04-27T01:17:40.209-07:00</atom:updated><title>Readability in Validation</title><description>My favourite pattern for validation code is to have one method per validation rule.  I think it makes it easier to read and manage the rules.&lt;br /&gt;&lt;br /&gt;For instance, I like to be able to write something like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;[Validate]&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; EndDateMustBeAfterStartDate()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; EndDate &amp;gt; StartDate;&lt;br /&gt;}&lt;/pre&gt;I like to refine the pattern a little, in order to: &lt;br /&gt;&lt;br /&gt;(a) Construct error messages based on the method names.  That makes the code more concise and encourages good method names.  E.g. the failure message from the rule above will be "End date must be after start date".  &lt;br /&gt;(b) Allow you to, alternatively, specify dynamically-generated failure messges from within the method body (see below)&lt;br /&gt;(c) Easily specify if the rule is not applicable in a particular situation (again see below).&lt;br /&gt;&lt;br /&gt;I've attached some &lt;a href="http://www.agilekiwi.com/dotnet/SimpleValidation.cs"&gt;sample code&lt;/a&gt; (with &lt;a href="http://www.agilekiwi.com/dotnet/SimpleValidationTests.cs"&gt;tests&lt;/a&gt;).  &lt;br /&gt;&lt;br /&gt;By the way, I &lt;a href="http://dotnet.agilekiwi.com/blog/2007/06/no-more-development-on-my-side-project.html"&gt;once&lt;/a&gt; wrote some code to fire rules automatically, whenever a property used by the rule was changed.  But that's not included here.  In this sample, you have to ask the system explictly to run the rules at a particular time. &lt;br /&gt;&lt;br /&gt;Here are some example rules, and the code to call them:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Animal&lt;br /&gt;{&lt;br /&gt;...&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; AnimalName&lt;br /&gt;{&lt;br /&gt;get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _animalName; }&lt;br /&gt;set { _animalName = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; NumberOfLegs&lt;br /&gt;{&lt;br /&gt;get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _numberOfLegs; }&lt;br /&gt;set { _numberOfLegs = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Validate]&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; Result NumberOfLegsMustBeEven()  &lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; NumberOfLegs % 2 == 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Validate]&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; Result MythicalSpeciesAreNotAllowed()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (AnimalName == &lt;span class="str"&gt;"Unicorn"&lt;/span&gt; || AnimalName == &lt;span class="str"&gt;"Dragon"&lt;/span&gt;)&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; Validation.Error(&lt;span class="str"&gt;"'"&lt;/span&gt; + AnimalName + &lt;span class="str"&gt;"' is not a real species"&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; Validation.NotApplicable;&lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// Note the use of the OR operator here to give a compact syntax for returning a custom error&lt;/span&gt;&lt;br /&gt;[Validate]&lt;br /&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; Result NumberOfLegsMustBePlausible()&lt;br /&gt;{&lt;br /&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; NumberOfLegs &amp;lt;= 10 || Validation.Error(&lt;span class="str"&gt;"Your '"&lt;/span&gt; + AnimalName +  &lt;span class="str"&gt;"' has too many legs"&lt;/span&gt;);&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;span class="rem"&gt;// execute like this&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt;(Result r &lt;span class="kwrd"&gt;in&lt;/span&gt; Validator&amp;lt;Animal&amp;gt;.ExecuteRulesOn(myAnimal))&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt;(!r.Pass)&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// or, like this, if you don't want to use the generic Validator class&lt;/span&gt;&lt;br /&gt;Validator v = Validator.GetInstanceFor(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Animal));&lt;br /&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Result r &lt;span class="kwrd"&gt;in&lt;/span&gt; v.ExecuteRulesOn(myAnimal))&lt;br /&gt;...&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24760385-2370804097451603149?l=dotnet.agilekiwi.com%2Fblog' alt='' /&gt;&lt;/div&gt;</description><link>http://dotnet.agilekiwi.com/blog/2008/01/readability-in-validation.html</link><author>noreply@blogger.com (John Rusk)</author><thr:total>2</thr:total></item></channel></rss>
