<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.lostechies.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Polyglots R Us</title><link>http://www.lostechies.com/blogs/rssvihla/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Newbie Win32 Development Using Python</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2010/01/15/newbie-win32-development-using-python.aspx</link><pubDate>Sat, 16 Jan 2010 04:35:33 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:47964</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=47964</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2010/01/15/newbie-win32-development-using-python.aspx#comments</comments><description>&lt;p&gt;First a disclaimer. I’m not in anyway shape or form an experienced win32 systems programmer.&amp;#160; I’ve always done application development or systems administration scripting. That in-between area where you get out your C/C++ compiler and start dealing with pointers is completely alien to me.&amp;#160; This has created problems in the past when I need to do something outside of the scope of C# and found myself staring at MSDN docs in C trying to extrapolate the equivalent C# code, and typically being disgusted at having to use hand rolled Structs with calls to Marshall.GetLastWin32Error().&lt;/p&gt;  &lt;p&gt;Worse still I end up with a nasty implementation that requires slow, fragile integration tests to verify behavior or very verbose mirror interfaces where I’m testing order of calls. Look at the following code sample to read a reparse point’s target directory from &lt;a href="http://www.codeproject.com/KB/vista/Windows_Vista.aspx" target="_blank"&gt;code project&lt;/a&gt;:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:ca4d7140-921c-43d6-926d-2fa0c33bf716" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;#160;&lt;span style="color:#008000"&gt;//&amp;#160;Allocate&amp;#160;a&amp;#160;buffer&amp;#160;for&amp;#160;the&amp;#160;reparse&amp;#160;point&amp;#160;data:&lt;br/&gt;
&lt;/span&gt;Int32&amp;#160;outBufferSize&amp;#160;=&amp;#160;Marshal.SizeOf(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(REPARSE_GUID_DATA_BUFFER));&lt;br/&gt;
IntPtr&amp;#160;outBuffer&amp;#160;=&amp;#160;Marshal.AllocHGlobal(outBufferSize);&lt;br/&gt;
&amp;#160;&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;try&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&lt;span style="color:#008000"&gt;//&amp;#160;Read&amp;#160;the&amp;#160;reparse&amp;#160;point&amp;#160;data:&lt;br/&gt;
&lt;/span&gt;Int32&amp;#160;bytesReturned;&lt;br/&gt;
&lt;span style="color:#008000"&gt;//&amp;#160;WOW&amp;#160;what&amp;#160;a&amp;#160;signature,&amp;#160;it's&amp;#160;requiring&amp;#160;blank&amp;#160;data!&amp;#160;&lt;br/&gt;
//&amp;#160;Looking&amp;#160;at&amp;#160;MSDN&amp;#160;the&amp;#160;signaure&amp;#160;contains&amp;#160;input&amp;#160;and&amp;#160;output&amp;#160;buffer&amp;#160;and&amp;#160;size&lt;br/&gt;
//&amp;#160;for&amp;#160;both,&amp;#160;meaning&amp;#160;I'm&amp;#160;always&amp;#160;sending&amp;#160;something&amp;#160;as&amp;#160;IntPtr.Zero&lt;br/&gt;
&lt;/span&gt;Int32&amp;#160;readOK&amp;#160;=&amp;#160;DeviceIoControl(&amp;#160;hFile,FSCTL_GET_REPARSE_POINT,&amp;#160;IntPtr.Zero,&amp;#160;0,&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;outBuffer,&amp;#160;outBufferSize,&amp;#160;&lt;span style="color:#0000ff"&gt;out&lt;/span&gt;&amp;#160;bytesReturned,IntPtr.Zero);&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;if&lt;/span&gt;&amp;#160;(readOK&amp;#160;!=&amp;#160;0)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//&amp;#160;Get&amp;#160;the&amp;#160;target&amp;#160;directory&amp;#160;from&amp;#160;the&amp;#160;reparse&amp;#160;&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//&amp;#160;point&amp;#160;data:&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;REPARSE_GUID_DATA_BUFFER&amp;#160;rgdBuffer&amp;#160;=&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;(REPARSE_GUID_DATA_BUFFER)Marshal.PtrToStructure(outBuffer,&amp;#160;&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(REPARSE_GUID_DATA_BUFFER));&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;targetDir&amp;#160;=&amp;#160;Encoding.Unicode.GetString(&amp;#160;rgdBuffer.PathBuffer,rgdBuffer.SubstituteNameOffset,&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;rgdBuffer.SubstituteNameLength);&lt;br/&gt;
&amp;#160;&amp;#160;&lt;br/&gt;
&lt;br/&gt;
	&lt;span style="color:#008000"&gt;//removed&amp;#160;a&amp;#160;bunch&amp;#160;more&amp;#160;stuff&amp;#160;to&amp;#160;format&amp;#160;the&amp;#160;result&lt;br/&gt;
&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;span style="color:#008000"&gt;//&amp;#160;Free&amp;#160;the&amp;#160;buffer&amp;#160;for&amp;#160;the&amp;#160;reparse&amp;#160;point&amp;#160;data:&lt;br/&gt;
&lt;/span&gt;&amp;#160;Marshal.FreeHGlobal(outBuffer);&lt;br/&gt;
&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In the past when building these kind of things for less complicated code I just would mirror out all the untestable code like Marshal , DeviceIoControl and CloseHandle calls with interfaces, then create a production wrapper.&amp;#160; This however leads to very long tests, with lots of specifics about the internals of the interaction, in the above example the support code looks like:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:6fd7931b-5a1c-4767-b0a0-234dc8ceb8ba" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;interface&lt;/span&gt;&amp;#160;IMarshal&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt;&amp;#160;FreeHGlobal(IntPtr&amp;#160;buffer);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Object&amp;#160;PtrToStructure(IntPtr&amp;#160;pointer,&amp;#160;Type&amp;#160;structure);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Int32&amp;#160;SizeOf(Type&amp;#160;structure);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;IntPtr&amp;#160;AllocHGlobal(&lt;span style="color:#2b91af"&gt;int&lt;/span&gt;&amp;#160;cb);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af"&gt;ProdMarshal&lt;/span&gt;&amp;#160;:&amp;#160;IMarshal&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt;&amp;#160;FreeHGlobal(IntPtr&amp;#160;buffer)&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Marshal.FreeHGlobal(buffer);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//&amp;#160;you&amp;#160;get&amp;#160;the&amp;#160;idea&amp;#160;from&amp;#160;here&amp;#160;&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;Not terribly pretty mocking and testing this leads to is it?&amp;#160; This isn’t also counting the win32 calls that are needed to setup and finalize the data around this. Before its all said and done to make this “testable” you end up with 2 interfaces, 2 wrapper production classes, and very heavy interaction specific mocking to even handle this basic idea of getting a value from a file system object.&amp;#160; Before you try and point out “well you can reuse that logic later” look at the size of Marshal and ask yourself do you really want to mock all that out? &lt;/p&gt;  &lt;p&gt;Adding insult to injury your mocks have to be very good to replicate the behavior of the actual real thing, and it varies greatly across platforms. Windows 7 and server 2008 r2 allow reparse points (or symlinks in the this case) from directory to directory, but Vista and 2008 r1 are a no go and will fail.&lt;/p&gt;  &lt;p&gt;No wonder the systems developers that I know completely turn there nose up at unit testing and instead focus on slow integration or systems tests. The abstractions take time to make happen and the code itself is just not testable without lots of mirrored interfaces.&lt;/p&gt;  &lt;p&gt;So not wanting to spend all my time just writing mirrored interfaces day in and out for win32 calls, nor liking the idea of turning my back on unit testing, I decided to take a look at dynamic languages win32 support. &lt;/p&gt;  &lt;p&gt;First I looked at Ruby and the win32 libraries I saw didn’t give me the above functionality I needed with the minimal amount of hassle I wanted. DeviceIoControl up there for example with its stunningly bad signature is still pretty rough in Ruby as they have a one to one signature mapping.&amp;#160; &lt;/p&gt;  &lt;p&gt;Python however has had for a very long time strong win32api support and removes some of the awful pain that you have to deal with. Below is the equivalent of the code above, again with items stripped out for brevity before and after it, but they’re roughly computationally equivalent and the Python version wins out more the more I include.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:aefd7317-9251-4a76-9ac6-022d1f37df4e" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#000000"&gt;output_buf&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;win32file&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;AllocateReadBuffer&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;winnt&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;MAXIMUM_REPARSE_DATA_BUFFER_SIZE&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;span style="color:#8f5902"&gt;&lt;i&gt;#notice&amp;#160;how&amp;#160;I&amp;#160;don't&amp;#160;have&amp;#160;to&amp;#160;pass&amp;#160;in&amp;#160;size&amp;#160;of&amp;#160;the&amp;#160;buffers&amp;#160;now.&amp;#160;I&amp;#160;still&amp;#160;have&amp;#160;the&amp;#160;need&amp;#160;to&amp;#160;&lt;/i&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#8f5902"&gt;&lt;i&gt;#&amp;#160;pass&amp;#160;None&amp;#160;in&amp;#160;for&amp;#160;the&amp;#160;input&amp;#160;buffer&amp;#160;here&amp;#160;however&lt;/i&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#000000"&gt;buf&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;win32file&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;DeviceIoControl&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;h&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;winioctlcon&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;FSCTL_GET_REPARSE_POINT&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#3465a4"&gt;None&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;OutBuffer&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;output_buf&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;Overlapped&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#3465a4"&gt;None&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&lt;span style="color:#000000"&gt;fixed_fmt&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#4e9a06"&gt;'LHHHHHH'&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;span style="color:#000000"&gt;fixed_len&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;struct&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;calcsize&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;fixed_fmt&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;span style="color:#000000"&gt;tag&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;datalen&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;reserved&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;target_offset&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;target_len&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;printname_offset&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;printname_len&lt;/span&gt;&amp;#160;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&amp;#160;\&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#000000"&gt;struct&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;unpack&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;fixed_fmt&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;buf&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;[:&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;fixed_len&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;])&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;It’s still not pretty, but its briefer, and I can actually stub out or test struct.calcsize, AllocateReadBuffer and DeviceIoControl with no need to mess around with setting up lots of test harness code. Using my current mocking framework the test code looks something like this:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:da33e42d-30b4-47e1-9763-600d8881661e" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#000000"&gt;alloc&lt;/span&gt;&amp;#160;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#000000"&gt;mock&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;replaceWithMock&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;win32file&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#4e9a06"&gt;"AllocateReadBuffer"&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#204a87"&gt;buffer&lt;/span&gt;&amp;#160;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#204a87"&gt;object&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;()&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#000000"&gt;alloc&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;stub&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#204a87"&gt;buffer&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#8f5902"&gt;&lt;i&gt;#removed&amp;#160;extra&amp;#160;setup&amp;#160;code&amp;#160;for&amp;#160;calcsize&amp;#160;and&amp;#160;DeviceIoControl&lt;/i&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#000000"&gt;getTargetDir&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;()&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#000000"&gt;mock&lt;/span&gt;&lt;span style="color:#ce5c00"&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;assertCalled&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#000000"&gt;win32file&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#4e9a06"&gt;"AllocateReadBuffer"&lt;/span&gt;&lt;span style="color:#000000"&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Much cleaner, much lower friction and so I’m satisfied with Python for win32 development so far.&amp;#160; I’ll give C# another look when I have the dynamic keyword and I don’t have to make explicit mirror interfaces for everything that’s untestable.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Newbie+Win32+Development+Using+Python&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2010%2f01%2f15%2fnewbie-win32-development-using-python.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2010%2f01%2f15%2fnewbie-win32-development-using-python.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=47964" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Python/default.aspx">Python</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/DotNet/default.aspx">DotNet</category></item><item><title>Adventures in Meta programming in Python: im_class, __import__, __getattribute__</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2010/01/08/adventures-in-meta-programming-in-python-im-class-import-getattribute.aspx</link><pubDate>Fri, 08 Jan 2010 05:03:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:46535</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=46535</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2010/01/08/adventures-in-meta-programming-in-python-im-class-import-getattribute.aspx#comments</comments><description>&lt;p&gt;With my recent work in Python win32 programming I&amp;rsquo;ve had a real need for AAA style mocking framework. Unable to find anything that I&amp;rsquo;ve been completely happy with I started my own simple mocking framework and got to learn some Python style meta programming&amp;nbsp; in the process. I&amp;rsquo;ve found out a lot about the depth of the Python 2.x object model over the last 2 weeks and here are some of the nicer things I&amp;rsquo;ve found (updated as per Chris Taveres below):&lt;/p&gt;
&lt;h3&gt;function_class = MyClass.foo.im_class &lt;/h3&gt;
&lt;p&gt;This is useful if you pass in an instance method&amp;nbsp; somewhere and you want to be able to access its attached class.&amp;nbsp; Decorators on instance methods normally use this, but I needed it to get a nicer syntax on my asserts, I wanted this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:4f580405-01ed-4fe2-b03f-97488b241b24" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
assertCalled(FakeRepo&lt;span style="color:#303030"&gt;.&lt;/span&gt;get)&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So now when I want to track what class is passed in I just have to start with the following:&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:dc19f439-3b79-4738-9d83-ec6e84ae0dae" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008000"&gt;&lt;strong&gt;def&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color:#0060B0"&gt;&lt;strong&gt;assertCalled&lt;/strong&gt;&lt;/span&gt;(method):&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;classdef&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;method&lt;span style="color:#303030"&gt;.&lt;/span&gt;im_class&amp;nbsp;&lt;span style="color:#808080"&gt;#I&amp;nbsp;get&amp;nbsp;the&amp;nbsp;method&amp;nbsp;and&amp;nbsp;the&amp;nbsp;class&amp;nbsp;in&amp;nbsp;one&amp;nbsp;parameter!&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;module = __import__(&amp;ldquo;foomodule&amp;rdquo;)&lt;/h3&gt;
&lt;p&gt;this creates a module import by string. This becomes super powerful say if you wanted to replace functionality on a module, but didn&amp;rsquo;t know its name before hand.&amp;nbsp; In my case I wanted to be able to patch in a replacement method for mocking and then put it back when I was done, and I didn&amp;rsquo;t want to have to keep passing in the module name on resets. The only downside to it so far is it behaves a little quirky with packages and you have walk your module hierarchy to get it to do what you want&lt;/p&gt;
&lt;p&gt;example of patching originals back into the module:&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:1617922f-90eb-4a49-a91f-3e226f85fda5" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008000"&gt;&lt;strong&gt;for&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;mod,&amp;nbsp;original&amp;nbsp;&lt;span style="color:#000000"&gt;&lt;strong&gt;in&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;_originals&lt;span style="color:#303030"&gt;.&lt;/span&gt;items():&amp;nbsp;&amp;nbsp;&lt;span style="color:#808080"&gt;#key&amp;nbsp;is&amp;nbsp;a&amp;nbsp;combination&amp;nbsp;of&amp;nbsp;module&amp;nbsp;name&amp;nbsp;and&amp;nbsp;methodname,&amp;nbsp;value&amp;nbsp;is&amp;nbsp;the&amp;nbsp;original&amp;nbsp;function&amp;nbsp;itself&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modulename&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;mod[&lt;span style="color:#6000E0"&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/span&gt;]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;methodname&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;mod[&lt;span style="color:#6000E0"&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/span&gt;]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color:#007020"&gt;__import__&lt;/span&gt;(modulename)&amp;nbsp;&amp;nbsp;&lt;span style="color:#808080"&gt;#this&amp;nbsp;is&amp;nbsp;the&amp;nbsp;magic.&amp;nbsp;if&amp;nbsp;module&amp;nbsp;name&amp;nbsp;has&amp;nbsp;no&amp;nbsp;package&amp;nbsp;aka&amp;nbsp;:&amp;nbsp;&amp;ldquo;barmod&amp;rdquo;&amp;nbsp;this&amp;nbsp;will&amp;nbsp;work.&amp;nbsp;if&amp;nbsp;its&amp;nbsp;&amp;ldquo;foopackage.barmod&amp;rdquo;&amp;nbsp;it&amp;rsquo;ll&amp;nbsp;import&amp;nbsp;the&amp;nbsp;&amp;ldquo;foopackage&amp;rdquo;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;&lt;strong&gt;for&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;i&amp;nbsp;&lt;span style="color:#000000"&gt;&lt;strong&gt;in&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;modulename&lt;span style="color:#303030"&gt;.&lt;/span&gt;split(".")[&lt;span style="color:#6000E0"&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/span&gt;:]:&amp;nbsp;&lt;span style="color:#808080"&gt;#works&amp;nbsp;down&amp;nbsp;the&amp;nbsp;chain&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color:#007020"&gt;getattr&lt;/span&gt;(module,&amp;nbsp;i)&amp;nbsp;&lt;span style="color:#808080"&gt;#resets&amp;nbsp;the&amp;nbsp;module&amp;nbsp;variable&amp;nbsp;with&amp;nbsp;the&amp;nbsp;lower&amp;nbsp;hierarchy&amp;nbsp;module&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#007020"&gt;setattr&lt;/span&gt;(module,&amp;nbsp;methodname,&amp;nbsp;original)&amp;nbsp;&lt;span style="color:#808080"&gt;#actually&amp;nbsp;pass&amp;nbsp;the&amp;nbsp;original&amp;nbsp;function&amp;nbsp;object&amp;nbsp;back&amp;nbsp;onto&amp;nbsp;the&amp;nbsp;module.&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;MyClass.__getattribute__ = interception&lt;/h3&gt;
&lt;p&gt;__getattribute__ is called when any attribute is accessed on a class including __getattribute__ itself which is a bit silly.&amp;nbsp; This was the primary engine of my mocking framework as it allowed me to record all calls to the methods on a mocked class.&amp;nbsp; Just remember when you use this to have it not call itself or you&amp;rsquo;ll be in endless recursion!&lt;/p&gt;
&lt;p&gt;example:&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:38906e7c-1ec2-4fb5-8691-d2ee80e31536" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008000"&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color:#B00060"&gt;&lt;strong&gt;MyClass&lt;/strong&gt;&lt;/span&gt;(&lt;span style="color:#007020"&gt;object&lt;/span&gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;&lt;strong&gt;def&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color:#0060B0"&gt;&lt;strong&gt;stuff&lt;/strong&gt;&lt;/span&gt;(&lt;span style="color:#007020"&gt;self&lt;/span&gt;):&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;&lt;strong&gt;pass&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#008000"&gt;&lt;strong&gt;def&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color:#0060B0"&gt;&lt;strong&gt;interceptor&lt;/strong&gt;&lt;/span&gt;(&lt;span style="color:#007020"&gt;self&lt;/span&gt;,&amp;nbsp;name):&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;&lt;strong&gt;if&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;name&amp;nbsp;&lt;span style="color:#303030"&gt;==&lt;/span&gt;&amp;nbsp;"__getattribute__":&amp;nbsp;&lt;span style="color:#808080"&gt;#guard&amp;nbsp;condition&amp;nbsp;against&amp;nbsp;calling&amp;nbsp;itself&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color:#007020"&gt;object&lt;/span&gt;&lt;span style="color:#303030"&gt;.&lt;/span&gt;__getattribute__(&lt;span style="color:#007020"&gt;self&lt;/span&gt;,&amp;nbsp;name)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#808080"&gt;#whatever&amp;nbsp;interception&amp;nbsp;logic&amp;nbsp;you&amp;nbsp;need&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
MyClass&lt;span style="color:#303030"&gt;.&lt;/span&gt;__getattribute__&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;interceptor&lt;br /&gt;
m&amp;nbsp;&lt;span style="color:#303030"&gt;=&lt;/span&gt;&amp;nbsp;MyClass()&lt;br /&gt;
m&lt;span style="color:#303030"&gt;.&lt;/span&gt;stuff()&amp;nbsp;&lt;span style="color:#808080"&gt;#interception&amp;nbsp;logic&amp;nbsp;will&amp;nbsp;be&amp;nbsp;called&amp;nbsp;here&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m just starting to dip into the Python object model now and I&amp;rsquo;ll try and share what I find over the next few weeks.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Adventures+in+Meta+programming+in+Python%3a+im_class%2c+__import__%2c+__getattribute__&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2010%2f01%2f08%2fadventures-in-meta-programming-in-python-im-class-import-getattribute.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2010%2f01%2f08%2fadventures-in-meta-programming-in-python-im-class-import-getattribute.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=46535" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Python/default.aspx">Python</category></item><item><title>Take 3: Python, ISP, IoC, and OCP need a fundamental rethink.</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/20/take-3-python-isp-ioc-and-ocp-need-a-fundamental-rethink.aspx</link><pubDate>Fri, 20 Nov 2009 19:23:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:33261</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=33261</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/20/take-3-python-isp-ioc-and-ocp-need-a-fundamental-rethink.aspx#comments</comments><description>&lt;p&gt;In response to Julian’s thoughtful &lt;a href="http://www.colourcoding.net/Blog/archive/2009/11/20/dynamic-languages-and-solid-principles.aspx" target="_blank"&gt;Dynamic Languages and SOLID Principles&lt;/a&gt; I’d have to argue he is about 95% there but is missing the last critical links needed to view this in a whole different light. For ISP, Julian says it all:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Ultimately, I don't think ISP is changed by Python, it's just kind of irrelevant, for better or worse.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Exactly!&amp;#160; Why even bother mentioning in the context of dynamic languages. A developer that understands it fully and one that does not will code the same way. Whereas LSP is still taught in dynamic languages, I’ve never seen it called that but I’ve seen many admonishments about subclass consistency, and not making client code aware of the differences, and is something that requires mentioning. With ISP we could ignore it’s entire existence and developers would code the same.&lt;/p&gt;  &lt;p&gt;For OCP:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Well, the open closed principle is a goal, not a design practice, but let's take a look at the danger points: &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; * &lt;strong&gt;You can't have non-virtual methods, so Python wins this hands down.&lt;/strong&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; * &lt;strong&gt;Your variable can't be made too specific, so you're safe there.&lt;/strong&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; * You can still compare against hard-coded values.&amp;#160; It's just as easy to get this wrong in Python as it is in C#.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; * Same holds true for Law of Demeter violations.&amp;#160; If you pass the wrong object around, your code will be just as fragile in Python as in C#. &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Python certainly reduces the scope for some OC violations&lt;/strong&gt;, but you've still got lots of rope to hang yourself.&amp;#160; Think you still need to bear the goal in mind.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Bolding emphasis is mine. Enough of OCP is stripped and the primary ways its taught and demonstrated do not apply to the language at all. Focus on Law of Demeter, but having something that stands for “Open for extension” whenever everything is open and “Closed for modification” when nothing is closed would fall on completely deaf ears when presenting any of the associated ideas to a Python developer.&lt;/p&gt;  &lt;p&gt;For Dependency Inversion/ IoC:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Let's quote Ryan: &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; Now all calls in this runtime, from any module, that reference the Output class will use XmlOutput or HtmlOutput instead. &lt;/p&gt;    &lt;p&gt;Yes, but what if I wanted only half of them?&amp;#160; Maybe there's Python techniques I don't know about (I'm barely competent in the language) but as I see it, I'm going to need to change the code.&amp;#160; I don't think that dependencies can &amp;quot;always&amp;quot; be injected.&amp;#160; They can only be done when it won't cause damage.&amp;#160; In his case, he's worrying about testability.&amp;#160; That's fine, but we all agree there's more to DI than testability.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ok firstly, I didn’t just mention testability, in fact that the code you’re referencing there was no unit test for, it was about flexibility.&amp;#160; Secondly, call Output an “Abstract Class”,and then call XmlOutput and HtmlOutput concrete types and then add them to an IoC container like Windsor then let me ask yourself the question you asked me “what if i wanted only half of them”.&amp;#160; There would be a need for custom code to make this resolution work for this custom circumstance.&amp;#160; All I’m advocating is taking that same exact custom code and place it somewhere else in Python (yes you can override per method, per instance, etc, etc).&amp;#160; &lt;/p&gt;  &lt;p&gt;I think there needs to be a principle that addresses the benefits of &lt;strong&gt;explicit&lt;/strong&gt; interfaces and well formed custom composition cases…and in those cases DI makes a lot more sense, but certainly not as a defacto convention and certainly is not required to provide flexibility to existing implementations.&amp;#160; It certainly becomes apparent when you start looking into the actual way IoC works in static languages its &lt;u&gt;all too similar to how a dynamic language runtime works&lt;/u&gt;. That code you’d use in a static language IoC to apply AOP, or custom composition rules, could just as easily be applied in a component in Python, &lt;u&gt;because the primary mechanism for an IoC to work is as a factory, and the benefits and features they bring are all derived from having access to how objects are created and then returned&lt;/u&gt;, when you always have access to how objects are created and returned anyway as in dynamic languages, why should you implement it a second time. 100% DI’d code will be more effort to maintain because it would be in C# too…if not for that fact the language is so “structured” that the flexibility and testability benefits gained &lt;strong&gt;far&lt;/strong&gt; outweigh the slightly increased cost (which is only brought down with the awesomeness of auto registering components).&amp;#160; In a language already with flexibility and testability whether you use DI or not AND without auto registering IoC containers the cost to maintain a full DI code base is I’d argue unacceptable. &lt;/p&gt;  &lt;p&gt;Summary, for SOLID to make any sense whatsoever in a dynamic context it has to amended and modified to fit that world. Maybe make SOLID into SELL for:&lt;/p&gt;  &lt;p&gt;S.RP &lt;/p&gt;  &lt;p&gt;E.xplicit empty class for required overrides&lt;/p&gt;  &lt;p&gt;L.SP&lt;/p&gt;  &lt;p&gt;L.aw of Demeter&lt;/p&gt;  &lt;p&gt;Maybe there is something containing other more valid concepts for the dynamic world that I’m probably not qualified to design or come up with. Anyway, I’ve enjoyed the conversation and I hope it brings about a firmer understanding of SOLID, and whatever we’ve not come up with yet for dynamic languages.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Take+3%3a+Python%2c+ISP%2c+IoC%2c+and+OCP+need+a+fundamental+rethink.&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f20%2ftake-3-python-isp-ioc-and-ocp-need-a-fundamental-rethink.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f20%2ftake-3-python-isp-ioc-and-ocp-need-a-fundamental-rethink.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=33261" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Dynamic+Langs/default.aspx">Dynamic Langs</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/IoC/default.aspx">IoC</category></item><item><title>Take 2: Why we use SOLID in static languages and how we get the same functionality for cheap in dynamic languages</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/19/take-2-why-we-use-solid-in-static-languages-and-how-we-get-the-same-functionality-for-cheap-in-dynamic-languages.aspx</link><pubDate>Thu, 19 Nov 2009 22:46:17 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:32828</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=32828</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/19/take-2-why-we-use-solid-in-static-languages-and-how-we-get-the-same-functionality-for-cheap-in-dynamic-languages.aspx#comments</comments><description>&lt;p&gt;One of the things we do pretty well at Los Techies is explaining SOLID principles and why they make our code more maintainable and if you’re not familiar with our work on SOLID,&amp;#160; read &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx" target="_blank"&gt;Chad Meyer's post&lt;/a&gt; to get an understanding on the Los Techies perspective. Now that you’ve taken a bit of time to read that the following chart takes SOLID’s benefits and then shows how they apply to dynamic languages:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table border="2" cellspacing="0" cellpadding="2" width="413"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;Principle&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Primary Benefit&lt;/td&gt;        &lt;td valign="top"&gt;Secondary Benefit&lt;/td&gt;        &lt;td valign="top" width="86"&gt;What dynamic langs do to replace said principle&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;Single Responsibility Principle (SRP)&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Classes are in understandable units&lt;/td&gt;        &lt;td valign="top"&gt;Testability&lt;/td&gt;        &lt;td valign="top" width="86"&gt;Nothing&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;Open-Closed Principle (OCP)&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Flexibility&lt;/td&gt;        &lt;td valign="top"&gt;Guidance&lt;/td&gt;        &lt;td valign="top" width="86"&gt;can override anything globally (monkey patch)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;Liskov Substitution Principle (LSP)&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Not bleeding subclass specific knowledge everywhere&lt;/td&gt;        &lt;td valign="top"&gt;Least surprise&lt;/td&gt;        &lt;td valign="top" width="86"&gt;Nothing&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;Interface Segregation Principle (ISP)&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Interfaces are in understandable units&lt;/td&gt;        &lt;td valign="top"&gt;Less work for interface implementation&lt;/td&gt;        &lt;td valign="top" width="86"&gt;everything’s an interface (duck typing)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top"&gt;Dependency Inversion Principle(DIP)&lt;/td&gt;        &lt;td valign="top" width="121"&gt;Flexibility&lt;/td&gt;        &lt;td valign="top"&gt;Testability&lt;/td&gt;        &lt;td valign="top" width="86"&gt;can override anything globally (monkey patch)&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The above is my opinion and I’m sure people will beat me to death because I’m just some dude not many people know about,&amp;#160; but I think I’ve got a grasp of what SOLID means in C# and I’ve grappled with it from a practical perspective.&lt;/p&gt;  &lt;p&gt;You’ll note when it comes to LSP and SRP dynamic languages really give you nothing at all, but OCP, ISP, and DI benefits wise are supplanted by language features in python, ruby, etc.&amp;#160; How does this happen? In the case of ISP and “duck typing” this should be pretty obvious, but in the cases of OCP, DIP&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;DIP/OCP testability achieved through C#:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:e5b017cf-53bf-4595-947f-f0e091cebf2b" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;FooBar&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/span&gt;&amp;#160;IFooService&amp;#160;_service;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;FooBar&lt;/b&gt;&lt;/span&gt;(IFooService&amp;#160;service)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;_service&amp;#160;=&amp;#160;service;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;DoFoo&lt;/b&gt;&lt;/span&gt;()&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;_service.run();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;//testcode&lt;br/&gt;
&lt;/span&gt;&lt;span style="color:#336699"&gt;&lt;br/&gt;
[TestFixture]&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;FooBarSpec&lt;/b&gt;&lt;/span&gt;&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#336699"&gt;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;[Test]&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;should_call_fooservice&lt;/b&gt;&lt;/span&gt;()&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;mockfoo&amp;#160;=&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&amp;#160;Mock&amp;lt;IFooService&amp;gt;();&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;foobar&amp;#160;=&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&amp;#160;FooBar(mockfoo.&lt;span style="color:#888888"&gt;&lt;b&gt;object&lt;/b&gt;&lt;/span&gt;);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;foobar.DoFoo();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;mockfoo.Verify(foo=&amp;gt;foo.run())&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;DIP/OCP equivalent testability achieved through Python:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:43448cf0-795f-4ea0-849f-d2a4ea4b9f61" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;FooBar&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;DoFoo&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;service&amp;#160;=&amp;#160;FooService()&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;service.run()&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;#test&amp;#160;code&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;unittest&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;TestFooBar&lt;/b&gt;&lt;/span&gt;(unittest.TestCase):&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;runmock&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#003388"&gt;self&lt;/span&gt;.fooservice_run_was_called&amp;#160;=&amp;#160;&lt;span style="color:#003388"&gt;True&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;test_do_fooservice_is_called&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;originalrun&amp;#160;=&amp;#160;FooService.run&amp;#160;&lt;span style="color:#888888"&gt;#storing&amp;#160;the&amp;#160;original&amp;#160;method&amp;#160;in&amp;#160;a&amp;#160;variable&amp;#160;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;FooService.run&amp;#160;=&amp;#160;&lt;span style="color:#003388"&gt;self&lt;/span&gt;.runmock&amp;#160;&amp;#160;&lt;span style="color:#888888"&gt;#&amp;#160;I'm&amp;#160;globally&amp;#160;overriding&amp;#160;the&amp;#160;method&amp;#160;call&amp;#160;FooService.run&amp;#160;AKA&amp;#160;Monkey&amp;#160;Patch&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;FooBar().DoFoo()&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;FooService.run&amp;#160;=&amp;#160;originalrun&amp;#160;&lt;span style="color:#888888"&gt;#globally&amp;#160;put&amp;#160;it&amp;#160;back&amp;#160;to&amp;#160;where&amp;#160;it&amp;#160;was&amp;#160;AKA&amp;#160;Monkey&amp;#160;Patch&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;assert&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#003388"&gt;self&lt;/span&gt;.fooservice_run_was_called&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;Now rightfully you may say the Python version has a few more lines of code, and it certainly can be considered ugly…but don’t you see that I replaced an &lt;strong&gt;entire mocking library&lt;/strong&gt; in a few lines of code.&amp;#160; There are also mocking libraries and monkey patch libraries for Python that would shorten my line of code count further.&amp;#160; Testability and flexibility dovetail, but the &lt;strong&gt;global accessibility of class definitions &lt;/strong&gt;is understandably hard to grasp for the static mindset (it took me months), so we’ll continue on to flexibility:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:5e9f357c-5a26-4e5b-a3bb-523f1138579f" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;interface&lt;/b&gt;&lt;/span&gt;&amp;#160;IOutput&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;&amp;#160;fileloc,&amp;#160;ResultObjects[]&amp;#160;results);&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;XmlOutput&lt;/b&gt;&lt;/span&gt;:IOutput&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;&amp;#160;fileloc,&amp;#160;ResultObjects[]&amp;#160;results)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#888888"&gt;//&amp;#160;place&amp;#160;xml&amp;#160;specific&amp;#160;code&amp;#160;here&lt;br/&gt;
&lt;/span&gt;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;HtmlOutput&lt;/b&gt;&lt;/span&gt;:&amp;#160;IOutput&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;&amp;#160;fileloc,&amp;#160;ResultObjects[]&amp;#160;results)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#888888"&gt;//&amp;#160;place&amp;#160;html&amp;#160;specific&amp;#160;code&amp;#160;here&lt;br/&gt;
&lt;/span&gt;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;TestRunner&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/span&gt;&amp;#160;IOutput&amp;#160;_output;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/span&gt;&amp;#160;ITests&amp;#160;_tests;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;StoreTestResults&lt;/b&gt;&lt;/span&gt;(IOutput&amp;#160;output,&amp;#160;ITests&amp;#160;tests)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;_output&amp;#160;=&amp;#160;output;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;_tests&amp;#160;=&amp;#160;tests;	&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;RunTestsFromDir&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;&amp;#160;testdirectory,&amp;#160;&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;&amp;#160;outfile)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;results&amp;#160;=&amp;#160;_tests.GetResults(testdirectory);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;_output.save(outputfile,&amp;#160;results)&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;//later&amp;#160;on&amp;#160;we&amp;#160;use&amp;#160;IoC&amp;#160;containers&amp;#160;to&amp;#160;make&amp;#160;this&amp;#160;chain&amp;#160;easy&amp;#160;&lt;br/&gt;
&lt;/span&gt;&lt;br/&gt;
pubilc&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;main&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#888888"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt;[]&amp;#160;args)&lt;span style="color:#008800"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#888888"&gt;//&amp;#160;imagine&amp;#160;contextual&amp;#160;resolution&amp;#160;is&amp;#160;happening&amp;#160;intelligently&amp;#160;&lt;br/&gt;
&lt;/span&gt;&amp;#160;&lt;span style="color:#888888"&gt;//&amp;#160;on&amp;#160;the&amp;#160;resolver&amp;#160;because&amp;#160;someone&amp;#160;did&amp;#160;some&amp;#160;cool&amp;#160;stuff&amp;#160;in&amp;#160;windsor&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;var&amp;#160;runner&amp;#160;=&amp;#160;testcontainer.Resolve&amp;lt;TestRunner&amp;gt;();&lt;br/&gt;
&amp;#160;&amp;#160;runner.RunTestsFromDir(args[&lt;span style="color:#0000DD"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;],&amp;#160;args[&lt;span style="color:#0000DD"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;]);&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In Python with “monkey patching” everything is “Open For Extension” and dependencies can “always” be injected. A code sample based on my last blog post but extended to include some more complete client code follows:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:8bd30a7f-33bf-4693-a44d-5561882617e3" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#888888"&gt;#in&amp;#160;module&amp;#160;outputlib&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;Output&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(fileloc,&amp;#160;results):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;XmlOutput&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(fileloc,results):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#dd2200"&gt;"""xml&amp;#160;specific&amp;#160;logic&amp;#160;here"""&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;HtmlOutput&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;save&lt;/b&gt;&lt;/span&gt;(fileloc,results):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#dd2200"&gt;"""xml&amp;#160;specific&amp;#160;logic&amp;#160;here"""&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;TestRunner&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;run_tests_from_dir&lt;/b&gt;&lt;/span&gt;(testdirectory,&amp;#160;outfile):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;tests&amp;#160;=&amp;#160;Tests()&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;output&amp;#160;=&amp;#160;Output()&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;output.save(&amp;#160;&amp;#160;outfile&amp;#160;&amp;#160;,&amp;#160;tests.get_results(testdirectory)&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;#rest&amp;#160;of&amp;#160;the&amp;#160;script&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;sys&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;outputlib&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;as&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;o&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
testdirectory&amp;#160;=&amp;#160;sys.argv[&lt;span style="color:#0000DD"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;]&lt;br/&gt;
outfile&amp;#160;=&amp;#160;sys.argv[&lt;span style="color:#0000DD"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;]&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;#160;outfile.endswith(&lt;span style="color:#dd2200"&gt;"xml"&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;o.Output&amp;#160;=&amp;#160;o.XmlOutput&amp;#160;&lt;span style="color:#888888"&gt;#globally&amp;#160;override&amp;#160;calls&amp;#160;to&amp;#160;Output&amp;#160;with&amp;#160;XmlOutput.&amp;#160;AKA&amp;#160;Monkey&amp;#160;Patch&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt;&amp;#160;outfile.endswith(&lt;span style="color:#dd2200"&gt;"html"&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;o.Output&amp;#160;=&amp;#160;o.HtmlOutput&amp;#160;&lt;span style="color:#888888"&gt;#globally&amp;#160;override&amp;#160;calls&amp;#160;to&amp;#160;Output&amp;#160;with&amp;#160;HtmlOutput&amp;#160;AKA&amp;#160;Monkey&amp;#160;Patch&lt;/span&gt;&lt;br/&gt;
runner&amp;#160;=&amp;#160;o.TestRunner()&lt;br/&gt;
runner.run_tests_from_dir(testdirectory,&amp;#160;outfile)&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;Again this is longer code than the c# example.. but we’ve replaced an &lt;strong&gt;entire IoC container&lt;/strong&gt; and whatever custom code we would have had to add to create custom dependency resolver for selecting HTML or XML output options has now been replaced by a simple if else if conditional at the beginning of the code base execution. &lt;strong&gt; Now all calls in this runtime, from any module, that reference the Output class will use XmlOutput or HtmlOutput instead&lt;/strong&gt;, all with “monkey patching”.&lt;/p&gt;  &lt;p&gt;Hopefully, from here the rest of the dominos will fall into place once you get the concepts above, and the things we rely on SOLID for are in some cases already there in dynamic languages. Consequentially, my dynamic code looks (now) nothing like my static code because I no longer have to use DI/IoC to achieve my desired flexibility and access to use proper unit tests.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Take+2%3a+Why+we+use+SOLID+in+static+languages+and+how+we+get+the+same+functionality+for+cheap+in+dynamic+languages&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f19%2ftake-2-why-we-use-solid-in-static-languages-and-how-we-get-the-same-functionality-for-cheap-in-dynamic-languages.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f19%2ftake-2-why-we-use-solid-in-static-languages-and-how-we-get-the-same-functionality-for-cheap-in-dynamic-languages.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=32828" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Python/default.aspx">Python</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Dynamic+Langs/default.aspx">Dynamic Langs</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/SOLID/default.aspx">SOLID</category></item><item><title>I recant my IoC! IoC containers in dynamic languages are silly.</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/16/i-recant-my-ioc-ioc-containers-in-dynamic-languages-are-silly.aspx</link><pubDate>Mon, 16 Nov 2009 22:28:33 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:31780</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=31780</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/11/16/i-recant-my-ioc-ioc-containers-in-dynamic-languages-are-silly.aspx#comments</comments><description>&lt;p&gt;After a year or so of solid Alt Dot Net infection (as far as infections go its a pretty awesome one to have), I decided to give Python a try again for more than one off sysadmin tasks, and to actually dive into it as a newly minted “Agilista”.&amp;#160; &lt;/p&gt;  &lt;p&gt;However, I had&amp;#160; a problem..there were no non-painful IoC containers in Python (sorry to the other authors of IoC frameworks in Python like Spring Python and Snake Guice, I know you try and I respect the effort).&amp;#160; Ultimately, I could &lt;u&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/u&gt;&amp;#160; imagine coding anymore without something to handle all my registration for me, that’d dynamically inject in my dependencies, give me hooks for contextual resolution, and give me rich interception support.&lt;/p&gt;  &lt;p&gt;So I built my own, it was painful still, but I had some ideas to move it in an Convention Over Configuration direction, and ultimately get within shooting range of what fancy stuff we’ve come to expect in .Net that Windsor, StructureMap and many others provide.&lt;/p&gt;  &lt;p&gt;Now as I got into the fancier aspects of dynamic languages, open classes and the ability to override &lt;strong&gt;all&lt;/strong&gt; behavior easily I get it…a dynamic languages runtime is like a bit IoC container.&lt;/p&gt;  &lt;p&gt;Now I’ve heard other people say this many times but rarely with explanation or example, or focus on frankly silly things like “Dependency Injection adds too many lines of code” which is a bit melodramatic. Two arguments to a constructor, two fields ,and then avoiding having to call new is not “adding too many lines of code”, especially with templates, IDE’s, scripting, etc to cut down the actual typing load.Today I’m going to actually try to explain how languages like Python, Ruby etc give us the same awesomeness we’ve come to expect in things like Windsor..but at a much cheaper cost of learning and dev time.&lt;/p&gt;  &lt;p&gt;Take a typical resolution scenario where you want to output to a different file format depending on command line switches.&amp;#160; With an IoC container you can either:&lt;/p&gt;  &lt;p&gt;Change the resolution argument to load a different concrete type:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:3dcbdc1b-494c-457b-9efd-ede9201abe6f" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#0000ff"&gt;if&lt;/span&gt;(arg&amp;#160;==&amp;#160;&lt;span style="color:#a31515"&gt;"XML"&lt;/span&gt;)&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;container.Register(Component.For&amp;lt;IOutput&amp;gt;().ImpmentedBy&amp;lt;XmlOutput&amp;gt;());&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&amp;#160;if(arg&amp;#160;==&amp;#160;&lt;span style="color:#a31515"&gt;"HTML"&lt;/span&gt;)&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;container.Register(Component.For&amp;lt;IOutput&amp;gt;().ImpmentedBy&amp;lt;HtmlOutput&amp;gt;());&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;container.Register(Component.For&amp;lt;IOutput&amp;gt;().ImpmentedBy&amp;lt;NullOutput&amp;gt;());&lt;br/&gt;
&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;   &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;or resolve different arguments or keys using a service locator approach in later client code (thereby depending on the container)&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:0f98bb6c-197e-44c9-884d-326c91be6373" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
	&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt;&amp;#160;output(IKernel&amp;#160;container,&amp;#160;&lt;span style="color:#2b91af"&gt;string&lt;/span&gt;&amp;#160;key)&lt;br/&gt;
	&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
		var&amp;#160;output&amp;#160;=container.Resolve&amp;lt;IOutput&amp;gt;(key);&lt;br/&gt;
		output.save();&lt;br/&gt;
&lt;br/&gt;
	&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;   &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;or implement a custom implementation of the resolver system (which I’ll leave out for the sake of brevity, but it’s not instant code).&amp;#160; Also to do all this you have to depend on interfaces, add all your interchangeable code to the constructor and life is grand.&amp;#160; You do this for many reasons in static languages, its the only way to get easy testability and code that is open to extension.&amp;#160; In dynamic languages its &lt;strong&gt;&lt;u&gt;always open for extension and easy to test&lt;/u&gt;&lt;/strong&gt; . Let me demonstrate:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:c306549e-c4ed-4b96-9589-57a9b432eba7" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;outputlib&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;as&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;o&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;outputselect&lt;/b&gt;&lt;/span&gt;(arg):&lt;br/&gt;
	&lt;span style="color:#008800"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;#160;arg&amp;#160;==&amp;#160;&lt;span style="color:#dd2200"&gt;"XML"&lt;/span&gt;:&lt;br/&gt;
		o.Output&amp;#160;=&amp;#160;XmlOutput&lt;br/&gt;
	&lt;span style="color:#008800"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt;&amp;#160;arg&amp;#160;==&amp;#160;&lt;span style="color:#dd2200"&gt;"HTML"&lt;/span&gt;:&lt;br/&gt;
		o.Output&amp;#160;=&amp;#160;HtmlOutput&lt;br/&gt;
	&lt;span style="color:#008800"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;:&lt;br/&gt;
		o.Output&amp;#160;=&amp;#160;NullOutput&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;saveoutput&lt;/b&gt;&lt;/span&gt;():&lt;br/&gt;
	o.Output().save()&amp;#160;&amp;#160;&lt;span style="color:#888888"&gt;#will&amp;#160;save&amp;#160;whichever&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Contextual resolution in a nutshell, and throughout your code if need be.&amp;#160; “Interception” is even easier, take a look at &lt;a title="http://docs.python.org/dev/library/functools.html" href="http://docs.python.org/dev/library/functools.html"&gt;http://docs.python.org/dev/library/functools.html&lt;/a&gt; and then start playing you’ll see you can trivially apply logging and security to methods without explicitly adding it. A short logging example follows:&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:21ea489c-0a45-4b0c-8ae4-cd4fbbf78b2e" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;types&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;import&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;functools&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;#applies&amp;#160;a&amp;#160;cepter&amp;#160;to&amp;#160;each&amp;#160;non-underscored&amp;#160;method.&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;wrapcls&lt;/b&gt;&lt;/span&gt;(cls,&amp;#160;cepter):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;publics&amp;#160;&amp;#160;=&amp;#160;[&amp;#160;name&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;#160;name&amp;#160;&lt;span style="color:#008800"&gt;in&lt;/span&gt;&amp;#160;&lt;span style="color:#003388"&gt;dir&lt;/span&gt;(cls)&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#008800"&gt;not&lt;/span&gt;&amp;#160;name.startswith(&lt;span style="color:#dd2200"&gt;"_"&lt;/span&gt;)]&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;methods&amp;#160;=&amp;#160;[&lt;span style="color:#003388"&gt;getattr&lt;/span&gt;(cls,method)&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;#160;method&amp;#160;&lt;span style="color:#008800"&gt;in&lt;/span&gt;&amp;#160;publics&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#003388"&gt;type&lt;/span&gt;(&lt;span style="color:#003388"&gt;getattr&lt;/span&gt;(cls,method))&amp;#160;==&amp;#160;types.MethodType&amp;#160;]&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;#160;method&amp;#160;&lt;span style="color:#008800"&gt;in&lt;/span&gt;&amp;#160;methods:&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;intercepted_method&amp;#160;=&amp;#160;cepter(method)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#003388"&gt;setattr&lt;/span&gt;(cls,&amp;#160;method.__name__,&amp;#160;intercepted_method)&amp;#160;&lt;span style="color:#888888"&gt;#attaches&amp;#160;intercepted_method&amp;#160;to&amp;#160;the&amp;#160;original&amp;#160;class,&amp;#160;replacing&amp;#160;non-intercepted&amp;#160;one&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;#the&amp;#160;magic&amp;#160;all&amp;#160;happens&amp;#160;in&amp;#160;the&amp;#160;functools.wraps&amp;#160;decorator&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;loggingcepter&lt;/b&gt;&lt;/span&gt;(func):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#555555"&gt;@functools&lt;/span&gt;.wraps(func)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;logafter&lt;/b&gt;&lt;/span&gt;(*args,&amp;#160;**kwargs):&amp;#160;&lt;span style="color:#888888"&gt;#for&amp;#160;csharp&amp;#160;devs&amp;#160;view&amp;#160;this&amp;#160;as&amp;#160;an&amp;#160;inline&amp;#160;delegate&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;result&amp;#160;=&amp;#160;func(*args,&amp;#160;**kwargs)&amp;#160;&lt;span style="color:#888888"&gt;#invoking&amp;#160;function&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"function&amp;#160;name:&amp;#160;"&lt;/span&gt;&amp;#160;+&amp;#160;func.__name__&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"arguments&amp;#160;were:&amp;#160;"&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;#160;a&amp;#160;&lt;span style="color:#008800"&gt;in&lt;/span&gt;&amp;#160;args:&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#003388"&gt;repr&lt;/span&gt;(a)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"keyword&amp;#160;args&amp;#160;were:&amp;#160;"&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&amp;#160;kword&amp;#160;&lt;span style="color:#008800"&gt;in&lt;/span&gt;&amp;#160;kwargs:&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#003388"&gt;repr&lt;/span&gt;(kword)&amp;#160;+&amp;#160;&lt;span style="color:#dd2200"&gt;"&amp;#160;:&amp;#160;"&lt;/span&gt;&amp;#160;+&amp;#160;&lt;span style="color:#003388"&gt;repr&lt;/span&gt;(kwargs[kword])&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"return&amp;#160;value&amp;#160;was:&amp;#160;"&lt;/span&gt;&amp;#160;+&amp;#160;&lt;span style="color:#003388"&gt;repr&lt;/span&gt;(result)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;#160;result&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;#160;logafter&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&lt;span style="color:#888888"&gt;#default&amp;#160;boring&amp;#160;repository&amp;#160;class&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;StorageEngine&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#555555"&gt;@property&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;connections&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;_sessioncall&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;create&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;,user):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"running&amp;#160;create&amp;#160;now&amp;#160;from&amp;#160;the&amp;#160;method"&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;delete&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;,&amp;#160;&lt;span style="color:#003388"&gt;id&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"running&amp;#160;delete&amp;#160;now&amp;#160;from&amp;#160;the&amp;#160;method"&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"deleted&amp;#160;from&amp;#160;the&amp;#160;database"&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;get&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;,&amp;#160;&lt;span style="color:#003388"&gt;id&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#0066bb"&gt;&lt;b&gt;__init__&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;self&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;span style="color:#888888"&gt;#placeholder&amp;#160;storage&amp;#160;object&lt;/span&gt;&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#bb0066"&gt;&lt;b&gt;User&lt;/b&gt;&lt;/span&gt;(&lt;span style="color:#003388"&gt;object&lt;/span&gt;):&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#008800"&gt;&lt;b&gt;pass&lt;/b&gt;&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
wrapcls(StorageEngine&amp;#160;,loggingcepter)&lt;br/&gt;
repo&amp;#160;=&amp;#160;StorageEngine()&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"calling&amp;#160;count&amp;#160;this&amp;#160;should&amp;#160;not&amp;#160;be&amp;#160;intercepted"&lt;/span&gt;&lt;br/&gt;
cnncount&amp;#160;=&amp;#160;repo.connections&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"now&amp;#160;get&amp;#160;should&amp;#160;be&amp;#160;intercepted"&lt;/span&gt;&lt;br/&gt;
repo.get(&lt;span style="color:#0000DD"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"we&amp;#160;should&amp;#160;see&amp;#160;keyword&amp;#160;arguments&amp;#160;here"&lt;/span&gt;&lt;br/&gt;
repo.delete(&lt;span style="color:#003388"&gt;id&lt;/span&gt;=&lt;span style="color:#0000DD"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"session&amp;#160;call&amp;#160;should&amp;#160;not&amp;#160;be&amp;#160;intercepted"&lt;/span&gt;&lt;br/&gt;
repo._sessioncall()&lt;br/&gt;
&lt;span style="color:#008800"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&amp;#160;&lt;span style="color:#dd2200"&gt;"create&amp;#160;should&amp;#160;be&amp;#160;intercepted&amp;#160;and&amp;#160;we&amp;#160;should&amp;#160;see&amp;#160;a&amp;#160;User&amp;#160;object"&lt;/span&gt;&lt;br/&gt;
repo.create(User())&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;   &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Running the above script should result in the following output&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rssvihla/Screenshot20091116at4.20.56PM_5F00_0C117192.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Screen shot 2009-11-16 at 4.20.56 PM" border="0" alt="Screen shot 2009-11-16 at 4.20.56 PM" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rssvihla/Screenshot20091116at4.20.56PM_5F00_thumb_5F00_49A1600C.png" width="625" height="530" /&gt;&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;So this is all very cool, but what does it mean or why do I care?&amp;#160; For those of us used to using a proper IoC container like Windsor or StructureMap, we’ve gotten used to have capabilities like the above easily available to us when we’ve needed them. It’s nice to find that in Python (or really any dynamic language ) we can easily build our own similar functionality that we’ve come to depend on.&amp;#160; We’re never coupled and we’re always able to test and mock out behavior.&amp;#160; It was a long time coming but I think I finally get it now.&lt;/p&gt;&lt;/blockquote&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=I+recant+my+IoC!+IoC+containers+in+dynamic+languages+are+silly.&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f16%2fi-recant-my-ioc-ioc-containers-in-dynamic-languages-are-silly.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f11%2f16%2fi-recant-my-ioc-ioc-containers-in-dynamic-languages-are-silly.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=31780" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Python/default.aspx">Python</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Dynamic+Langs/default.aspx">Dynamic Langs</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/IoC/default.aspx">IoC</category></item><item><title>Alt.Net Evangelism And What We Could Do Better</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/13/alt-net-evangelism-and-what-we-could-do-better.aspx</link><pubDate>Mon, 14 Sep 2009 00:06:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24810</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=24810</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/13/alt-net-evangelism-and-what-we-could-do-better.aspx#comments</comments><description>&lt;p&gt;If we assume our goal as the Alt.Net community is to improve software development as a whole, we're doing a pretty bad job. &amp;nbsp;Not that many people have even heard of the concepts we espouse, and those that have but didn't convert become hostile to our ideas.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My theory is because we focus so much on things that at the surface seem extraordinarily complex. Our terminology while correct, is acryonym laden and hard to grasp the real meaning. We ourselves sometimes lose site of why we even care about some of those principles, why we enacted them in the first place and what pain they caused to begin with. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;I'm not the first person to say or think this, but this has really hit home with me lately since now I get to talk to developers who are brilliant, talented and overall effective at what they do but who consider XP+SOLID a bunch of "enterprise junk" that fights against "natural coding" and my personal favorite "Unit testing is just testing your tests" .&lt;/p&gt;
&lt;p&gt;I've tried to talk to people in a reasonable way when I hear things like this, but usually before I know it, the alphabet soup of acronyms is out of my mouth, BDD, DDD, on and on. Even as a hungry student those terms shut my brain down when I first heard them, &amp;nbsp;so why would I expect someone who feels they know what goes into software development to have a different reaction?&lt;/p&gt;
&lt;p&gt;Since my goal is to do my small humble part to improve software development as a whole I'm going to try something new. If someone feels pain in the development process, then I'll speak up with a &lt;span style="text-decoration: underline;"&gt;solution&lt;/span&gt;&amp;nbsp;and focus my language on the solution only. Because really thats what all these ideas and concepts are, solutions to big pain points. &lt;/p&gt;
&lt;p&gt;The terms we use to describe them are unfortunately for the already intiated. Inversion Of Control, did any of you understand that without looking at code examples first? Behavior Driven Development, how many of you thought you knew what that was, practiced it, then realized that it means something else. &amp;nbsp;Just spouting off a bunch of acryonyms only excites the already curious who just have to know what they mean and for better or for worse they do not make up the bulk of the software development community. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;As for blogging thats a tough break, I use blogging as part envangelism, part bouncing ideas off my peers and superiors. &amp;nbsp;For the later I do need to actually use our alphabet soup to communicate, but for evangelism I'm afraid I contribute to turning off devs who are only googling for a solution.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Feedback?Ideas?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Alt.Net+Evangelism+And+What+We+Could+Do+Better&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f13%2falt-net-evangelism-and-what-we-could-do-better.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f13%2falt-net-evangelism-and-what-we-could-do-better.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24810" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/alt.net/default.aspx">alt.net</category></item><item><title>Playing With Haskell</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/01/playing-with-haskell.aspx</link><pubDate>Wed, 02 Sep 2009 03:53:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24485</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=24485</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/01/playing-with-haskell.aspx#comments</comments><description>&lt;p&gt;My tech book club is starting to look at Haskell. I'm as big of a language addict as anyone so I wanted to dive in early and this is the overview of what I've found so far&lt;/p&gt;
&lt;h3&gt;Statically Typed But Dynamically Inferred&lt;/h3&gt;
&lt;p&gt;for those of you familiar with Boo this is a familiar concept to you.  Once a type is made that type will not autoconvert. For Example:&lt;/p&gt;
&lt;p&gt;
let i = 6 --this is now going to be an integer
&lt;/p&gt;
&lt;p&gt;let f = 1.2 --this is now a float
&lt;/p&gt;
&lt;p&gt;i + f /--will throw exception
&lt;/p&gt;
&lt;h3&gt;Cannot set variable twice&lt;/h3&gt;
&lt;p&gt;this is from what I understand something that all functional languages share some concept of. (Erlang views the second attempt to set a variable as a "match" request).&lt;/p&gt;
&lt;p&gt;
x = 10&lt;/p&gt;
&lt;p&gt;
x = 11&lt;/p&gt;
&lt;p&gt;
when running the source file results in:
    &lt;/p&gt;
&lt;p&gt;Multiple declarations of `Main.x'
&lt;/p&gt;
&lt;p&gt;    Declared at: functions.hs:1:0
                 functions.hs:2:0
&lt;/p&gt;
&lt;p&gt;Failed, modules loaded: none.	
&lt;/p&gt;
&lt;h3&gt;My Least Favorite Thing In Python AKA Significant Whitespace&lt;/h3&gt;
&lt;p&gt;
In the above code file in my previous example I had an error with an extra whitespace hiding about. I got used to this in Python by using soft tabs and being aware of phantom white space. Not happy about this.
&lt;/p&gt;
&lt;h3&gt;No Loops!&lt;/h3&gt;
&lt;p&gt;The two primary ways I've found to replace loops are recursion and map.  Map is a standard of functional languages and pretty easy to grasp. It's just a way of saying "run a specified function on each item in the list". A quick example of map is as follows:&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;doubleList ls = map doubleInt ls -- function named "doublelist" with parameter of ls&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where doubleInt x = x*2&amp;nbsp;&amp;nbsp; --doubles x which represents each value in list&lt;br /&gt;&lt;br /&gt;doubled = doubleList [1,2,3,4,5] --set global variable with function applied&lt;/p&gt;
&lt;h3&gt;At A Glance&lt;/h3&gt;
&lt;p&gt;
Haskell seems to have an easier to learn syntax than Erlang, while still being less ceremonial than other languages I've used.  I kinda dig the no parenthesis syntax of functions, and of course I don't miss foreach loops with map.
Finally, I'll be anxious to find out what the multi-core story is vs Erlang.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Playing+With+Haskell&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f01%2fplaying-with-haskell.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f01%2fplaying-with-haskell.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24485" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Learning/default.aspx">Learning</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/GHC/default.aspx">GHC</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Functional/default.aspx">Functional</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Haskell/default.aspx">Haskell</category></item><item><title>Simple BDD/TDD</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/01/simple-bdd-tdd.aspx</link><pubDate>Wed, 02 Sep 2009 02:47:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24482</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=24482</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/09/01/simple-bdd-tdd.aspx#comments</comments><description>&lt;p&gt;Todays theory is &lt;b&gt;most tests and specs should be very short (2-3 lines), have at most a setup for context establishment, avoid the majority of test framework features as they should be used as an exception and not as a rule.&lt;/b&gt;&amp;nbsp; Note: I practice BDD nowadays and do not like using the term "test", but these rules apply for BDD as well as TDD, and I imagine most of you practice TDD so I'll be using primarily TDD terminology.&lt;/p&gt;
&lt;p&gt;If you look at my first attempts at TDD they are very similar to my current BDD work with only changes in language. But the contexts, conditions and tests are similar. Most importantly they're easy to read.  They're all very short, very descriptive, make limited use of arguments in the NUnit Attributes, and make very limited use of mocking.&lt;/p&gt;
&lt;p&gt;Of course along the way I went down all sorts of terrible wrong paths, and with the help of &lt;a href="http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1251858264&amp;amp;sr=8-1"&gt;Gerrard Meszaros&lt;/a&gt; plus some of my own experimentation I'm much happier with the time it takes to implement tests and the limited pain in refactoring my code.&lt;/p&gt;
&lt;p&gt;Bad ideas I had along the way include:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ran everything in TestFixtureSetup and TestFixtureTearDown or equivalent. Tests were all linked to one another&lt;/li&gt;
&lt;li&gt;Mocked EVERYTHING and doing so with Record/Replay was double awful. Simple refactorings would break way more tests than they should. Test methods were 8-40 lines and unreadable at that.&lt;/li&gt;
&lt;li&gt;Tried to sort everything by category with NUnit attributes. Took a fair amount of time for no payoff I can see (think about changing a category name when all you have is seemingly unrelated strings)&lt;/li&gt;
&lt;li&gt;Tried to create "Story Classes" for testing. I know some people like this approach, I find them to be heavily coupled, fragile and noisy. Also this made finding individual examples of usage of individual classes difficult as now its "rules" were spread everywhere&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Summary point avoid some of my mistakes, if you write short unit tests now..thats probably a good thing. If you are struggling with testability of your classes and you find your tests getting big, try and stop, sit down and make sure you are testing "one thing" and not really a big thing with many small pieces.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Simple+BDD%2fTDD&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f01%2fsimple-bdd-tdd.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f09%2f01%2fsimple-bdd-tdd.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24482" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/BDD/default.aspx">BDD</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Dynamic Loading of .Net Assemblies</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/31/dynamic-loading-of-net-assemblies.aspx</link><pubDate>Mon, 31 Aug 2009 22:29:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24422</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=24422</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/31/dynamic-loading-of-net-assemblies.aspx#comments</comments><description>&lt;p&gt;Problem: You have dependencies which can be in a number of directories outside of the directory your app is running in. DotNet AppDomains are heavy to say the least and very high in ceremony.&amp;#160; You do not want to deal with secondary app domain creation.&lt;/p&gt;  &lt;p&gt;Solution: Override&amp;#160; AssemblyResolve event on your current app domain.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:7890ae13-0ecd-4542-a07d-7440155adeb6" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af"&gt;AppDomainLoader&lt;/span&gt;&amp;#160;:&amp;#160;IAppDomainLoader&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt;&amp;#160;ResolveEventHandler&amp;#160;_searchAssemblyMethod&amp;#160;=&amp;#160;_searchDir;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;ResolveEventHandler&amp;#160;FindAssemblyMethod&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;set&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&amp;#160;_searchAssemblyMethod&amp;#160;=&amp;#160;&lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af"&gt;string&lt;/span&gt;[]&amp;#160;_directoriesToSearch;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;static&lt;/span&gt;&amp;#160;Assembly&amp;#160;_searchDir(Object&amp;#160;o,&amp;#160;ResolveEventArgs&amp;#160;e)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;&amp;#160;(var&amp;#160;s&amp;#160;&lt;span style="color:#0000ff"&gt;in&lt;/span&gt;&amp;#160;_directoriesToSearch)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;filetoload&amp;#160;=&amp;#160;s&amp;#160;+&amp;#160;&amp;#160;e.Name.Split(&lt;span style="color:#a31515"&gt;','&lt;/span&gt;)[0]&amp;#160;+&amp;#160;&lt;span style="color:#a31515"&gt;".dll"&lt;/span&gt;;&amp;#160;&lt;span style="color:#008000"&gt;//bad&amp;#160;one&amp;#160;liner&amp;#160;that&amp;#160;parses&amp;#160;the&amp;#160;first&amp;#160;part&amp;#160;of&amp;#160;the&amp;#160;assembly&amp;#160;name&amp;#160;and&amp;#160;adds&amp;#160;.dll&amp;#160;at&amp;#160;the&amp;#160;end&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;if&lt;/span&gt;&amp;#160;(File.Exists(filetoload))&amp;#160;&lt;span style="color:#008000"&gt;//sees&amp;#160;if&amp;#160;the&amp;#160;file&amp;#160;is&amp;#160;even&amp;#160;in&amp;#160;the&amp;#160;directory&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt;&amp;#160;Assembly.LoadFrom(filetoload);&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//returns&amp;#160;assembly&amp;#160;once&amp;#160;found,&amp;#160;a&amp;#160;bit&amp;#160;naive&amp;#160;and&amp;#160;does&amp;#160;not&amp;#160;handle&amp;#160;version&amp;#160;conflicts&amp;#160;well.&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt;&amp;#160;Search(&lt;span style="color:#2b91af"&gt;string&lt;/span&gt;[]&amp;#160;directoriesToSearch)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;_directoriesToSearch&amp;#160;=&amp;#160;directoriesToSearch;&amp;#160;&lt;span style="color:#008000"&gt;//sets&amp;#160;directories&amp;#160;to&amp;#160;search&amp;#160;to&amp;#160;allow&amp;#160;entry&amp;#160;point&amp;#160;for&amp;#160;dynamic&amp;#160;searching&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;AppDomain.CurrentDomain.AssemblyResolve&amp;#160;-=&amp;#160;_searchAssemblyMethod;&amp;#160;&lt;span style="color:#008000"&gt;//cleans&amp;#160;up&amp;#160;previous&amp;#160;events,&amp;#160;may&amp;#160;not&amp;#160;be&amp;#160;needed.&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;AppDomain.CurrentDomain.AssemblyResolve&amp;#160;+=&amp;#160;_searchAssemblyMethod;&amp;#160;&lt;span style="color:#008000"&gt;//registered&amp;#160;the&amp;#160;event&lt;br/&gt;
&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;Now whenever there is a missing Assembly, the _searchAssemblyMethod will be fired,&amp;#160; and all directories given to the Search method will attempt to find an assembly with the matching name.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Dynamic+Loading+of+.Net+Assemblies&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f31%2fdynamic-loading-of-net-assemblies.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f31%2fdynamic-loading-of-net-assemblies.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24422" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/DotNet/default.aspx">DotNet</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/AppDomain/default.aspx">AppDomain</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Hate/default.aspx">Hate</category></item><item><title>Focused and Narrow; Superficial and Broad</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/30/focused-and-narrow-superficial-and-broad.aspx</link><pubDate>Sun, 30 Aug 2009 15:12:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24363</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=24363</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/30/focused-and-narrow-superficial-and-broad.aspx#comments</comments><description>&lt;p&gt;In my 20's I got exposed to a large variety of work situations and was able to succeed in a variety of technical fields (admin, developer, hardware tech, etc). I had the time back then to not have to choose which direction I went with things, I went broad but deep into each field I was interested in. Every couple of years I'd go head long into another field and read dozen books, setup labs experiment like crazy, use whatever connections I'd made to get my foot in the door somewhere and then make sure I delivered in big ways, and most importantly keep reviewing what I'd done in the past to make sure it actually did work and did work well.&lt;/p&gt;
&lt;p&gt;This obsessive learning habit had a great side effect, as long as I stuck to slightly related fields I learned exponentially more. Learning about networking made helping customers with a variety of issues far easier when I was just a lowly computer tech.&amp;nbsp; When I was trying to automate customer installations in a repeatable way, learning software development even at a trivial level made things possible that were not otherwise.&amp;nbsp; I got to see how everythign interconnected.&lt;/p&gt;
&lt;p&gt;Nowadays though I have a busy life, I no longer can work 80+ hours a week year round, while studying, practicing or experimenting with the rest of my time. I now have to choose which way to do I go. I think I'm mostly going "Focused and Narrow" on a few subfields that are closely related to one another. I will focus for the near future on systems development and virtualization, I'll still probably be a language addict and wanting to do it a number of different ways, but I think for awhile I need to consildate my limited time and energy. I hope I don't lose my larger view and perspective on things, but I doubt I can any longer keep up with new versions of Postfix, Exchange, or Qmail, motherboard slot types, RAM, or whatever things that I used to know in much greater detail than I do now.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Focused+and+Narrow%3b+Superficial+and+Broad&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f30%2ffocused-and-narrow-superficial-and-broad.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f30%2ffocused-and-narrow-superficial-and-broad.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24363" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Learning/default.aspx">Learning</category></item><item><title>“Hero Mode Refactoring” AKA Enemy Of Brown Field Development</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/14/hero-mode-refactoring-aka-enemy-of-brown-field-development.aspx</link><pubDate>Fri, 14 Aug 2009 06:48:56 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:23716</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=23716</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/14/hero-mode-refactoring-aka-enemy-of-brown-field-development.aspx#comments</comments><description>&lt;p&gt;What do I mean by “Hero Mode Refactoring”?&amp;#160; We’ve all worked with code that wasn’t easily made testable. Most of the time we see a big ball of mud and have no idea where to begin. Sometimes however we have an epiphany, a _great_idea_ , a “cold fusion” moment (that ends up being poignant in so many ways).&amp;#160; &lt;/p&gt;  &lt;p&gt;Filled with the excitement of our vision we dive head long into our work, replacing concrete classes with interfaces, removing big swaths of redundant code, and in general making changes you should only make with a an already unit tested code base.&amp;#160; Before we know it, 5 things are broken in weird ways, and it now takes us days of manual verification to figure out what works and what doesn’t.&amp;#160; That is hero mode refactoring at its best.&lt;/p&gt;  &lt;p&gt;This situation reminds me a great deal of the difficulties I had with getting back in shape. I was a pretty decent athlete in my college days, but the real world had other ideas. Years later I tried to get back in shape several times, each time I tried my hardest right off the bat, and most of the time got injured in the process.&amp;#160; It wasn’t until age had given me some patience that I was able to actually get back in the gym in a consistent way. I had to work on the areas I could handle in a gradual way, instead of going 100% day 1.&amp;#160; I wasted years trying to get to 19 year old me in a month, but it only took me 6 months going the gradual way to be in decent shape.&lt;/p&gt;  &lt;p&gt;So too our codebases will behave if we try and go full out on day 1. That code didn’t get that way overnight, and usually cannot be fixed overnight.&amp;#160; Take a “siege” mentality into your code maintenance and realize this is a battle best fought gradually.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=%e2%80%9cHero+Mode+Refactoring%e2%80%9d+AKA+Enemy+Of+Brown+Field+Development&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f14%2fhero-mode-refactoring-aka-enemy-of-brown-field-development.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f14%2fhero-mode-refactoring-aka-enemy-of-brown-field-development.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=23716" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/BDD/default.aspx">BDD</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/TDD/default.aspx">TDD</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Brownfield/default.aspx">Brownfield</category></item><item><title>Introducing SpecMaker “Rspec style” BDD in C#</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/08/introducing-specmaker-rspec-style-bdd-in-c.aspx</link><pubDate>Sat, 08 Aug 2009 12:00:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:23528</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=23528</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/08/introducing-specmaker-rspec-style-bdd-in-c.aspx#comments</comments><description>&lt;p&gt;So I&amp;rsquo;m certain this will be met with mixed response, because really .Net already has several decent BDD frameworks and many of you will chastise me for adding yet another framework when really BDD has nothing to do with what testing framework you use.&amp;nbsp; So why you ask?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Most of the BDD frameworks I&amp;rsquo;ve looked at are Acceptance style and trying to make stories into executable code (NBehave, StoryTeller, Fitnesse.Net ,Acceptance, etc).&amp;nbsp; I want something that describes to other developers in a behavior centric way what my code is doing (like RSpec&amp;rsquo;s default DSL does).&amp;nbsp; This is not aimed at business analysts.&lt;/li&gt;
&lt;li&gt;The other RSpec style framework for C# I&amp;rsquo;ve played with while very nice, did not go over well with people I&amp;rsquo;ve tried to introduce to BDD.&lt;/li&gt;
&lt;li&gt;Using NUnit in a context BDD style is normally what I do but produces a lot of artifacts, is underscore heaven and provides no guidance to newer practitioners of BDD.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With all this in mind how does SpecMaker improve our situation at all?&amp;nbsp; First lets look at how I might approach a BDD test with NUnit&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:d3de05f6-f60f-4fa2-899e-857e108d427d" class="wlWriterEditableSmartContent"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;[TestFixture]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;SpecGameWhenStartingUp&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&amp;nbsp;Game&amp;nbsp;_game;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&amp;nbsp;startGame()&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&amp;nbsp;left&amp;nbsp;out&amp;nbsp;for&amp;nbsp;clarity&lt;br /&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[SetUp]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&amp;nbsp;SetUp()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startGame();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Test]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&amp;nbsp;should_have_3_lives()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.AreEqual(3,&amp;nbsp;_game.lives);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On the surface there isn&amp;rsquo;t much wrong with this. Asserts are less than ideal (Rspec matchers would be nice), underscores on my &amp;ldquo;should_&amp;rdquo; are so so, context in the class name leads to lots of classes and me playing around a bunch with inheritance. However, none of this is a game breaker and for those of you who have a good workable flow with this approach and are happy with it, please continue to use it. I however, am not happy with the flow, also BDD really is not easy for me to teach. Some of you may get it easily and teach it easily, but .Net developers as a whole seem to be driven towards framework specific knowledge (telling them to not think &amp;ldquo;test&amp;rdquo; when test is staring at them on the method messes with their heads), and even then it&amp;rsquo;d better not be too &amp;ldquo;cutting edge&amp;rdquo; in language features or friction becomes a risk where someone may end up learning more than just BDD.&lt;/p&gt;
&lt;p&gt;So what are my goals then for SpecMaker? &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It has to be terse, and be shorter than the NUnit approach.&lt;/li&gt;
&lt;li&gt;Eliminate underscores where possible.&lt;/li&gt;
&lt;li&gt;Act as a series of guidelines to beginning BDD&amp;rsquo;ers.&lt;/li&gt;
&lt;li&gt;Output spec results in a variety of formats.&lt;/li&gt;
&lt;li&gt;Remove the &amp;ldquo;Test&amp;rdquo; entirely from the vocabulary.&lt;/li&gt;
&lt;li&gt;Use convention over configuration where possible.&lt;/li&gt;
&lt;li&gt;Provide custom matchers and a DSL to make your own custom matchers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What will it not do or be?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do acceptance testing. This could change in the future, but then I&amp;rsquo;d be inclined to borrow code from others that do this well already.&lt;/li&gt;
&lt;li&gt;Make BDD a &amp;ldquo;click next&amp;rdquo; thing. There is no substitute for continually trying to refine your approach and understand &amp;ldquo;behavior&amp;rdquo; and what that means. I&amp;rsquo;m not sure there is one true right answer here and that makes it so incredibly hard to make a framework that does that.&lt;/li&gt;
&lt;li&gt;Be as nice as RSpec. &lt;/li&gt;
&lt;li&gt;Integration tests. This is setup very much one-to-one. Again this was a simplicity choice and as I dog food this I may completely change my mind here.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So with all the ceremony out of the way here is where I&amp;rsquo;m at so far for the same BDD code above only with SpecMaker&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:b060130c-d32e-4c37-b05d-e4b9a378e89f" class="wlWriterEditableSmartContent"&gt;
&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;nbsp;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;GameSpec&lt;/span&gt;&amp;nbsp;:&amp;nbsp;BaseSpec&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&amp;nbsp;startGame()&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//left&amp;nbsp;out&amp;nbsp;for&amp;nbsp;clarity&lt;br /&gt;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&amp;nbsp;when_starting_a_game()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startGame();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;should(&lt;span style="color: #a31515;"&gt;"have&amp;nbsp;3&amp;nbsp;lives"&lt;/span&gt;,&amp;nbsp;()=&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;{&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_game.lives.Has(3).Total();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;should(&lt;span style="color: #a31515;"&gt;"require&amp;nbsp;valid&amp;nbsp;username"&lt;/span&gt;,&amp;nbsp;RuleIs.Pending);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt; Running specmaker.exe on the the dll where this spec is located outputs something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rssvihla/Picture2_5F00_42D19A1D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Picture 2" alt="Picture 2" src="http://www.lostechies.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rssvihla/Picture2_5F00_thumb_5F00_14E6D816.png" border="0" width="750" height="82" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;At this time specs come from the class name minus &amp;ldquo;Spec&amp;rdquo; at the end. Context start with &amp;ldquo;when&amp;rdquo; or the method will not get picked up as context.&amp;nbsp; This is also staggeringly new and may have bugs, issues, bad docs, ugly code, etc. But since I&amp;rsquo;ve moved this to Github I encourage everyone to have a go and improve it as they see fit or for their own purposes.&amp;nbsp; I have a number of plans and ideas to improve this, but I feel this is a good start to get some positive work done and save myself some grief over my NUnit based tests.&lt;/p&gt;
&lt;p&gt;Let me know what you think, any and all criticism is appreciated, but at the end of the day this does actually fulfill an itch that I myself have had for some time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Introducing+SpecMaker+%e2%80%9cRspec+style%e2%80%9d+BDD+in+C%23&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f08%2fintroducing-specmaker-rspec-style-bdd-in-c.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f08%2fintroducing-specmaker-rspec-style-bdd-in-c.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=23528" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Spec/default.aspx">Spec</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/BDD/default.aspx">BDD</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Context/default.aspx">Context</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/SpecMaker/default.aspx">SpecMaker</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Windsor style convention over configuration in StructureMap</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/07/windsor-style-convention-over-configuration-in-structuremap.aspx</link><pubDate>Fri, 07 Aug 2009 12:47:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:23527</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=23527</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/08/07/windsor-style-convention-over-configuration-in-structuremap.aspx#comments</comments><description>&lt;p&gt;So I was trying to get my&amp;#160; BDD project &lt;a href="http://github.com/rssvihla/specmaker/tree/master" target="_blank"&gt;SpecMaker&lt;/a&gt; working on Mono only to find out&amp;#160; my usual IoC container of choice &lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt;Castle Windsor&lt;/a&gt; does not play nice.&amp;#160; &lt;a href="http://structuremap.sourceforge.net/Default.htm" target="_blank"&gt;StructureMap&lt;/a&gt; I’ve heard plays nice in Mono, and I know a bunch of people that use it, so I gave it a whirl.&lt;/p&gt;  &lt;p&gt;My original Windsor configuration looked something like this:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:c532398a-3f2f-46e1-a685-6428e342a668" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;#160;var&amp;#160;kernel&amp;#160;=&amp;#160;&lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&amp;#160;DefaultKernel();&lt;br/&gt;
&amp;#160;kernel.Register(Component.For&amp;lt;IReportFactory&amp;gt;().ImplementedBy(factory));&amp;#160;&lt;span style="color:#008000"&gt;//load&amp;#160;implementation&lt;br/&gt;
&lt;/span&gt;&amp;#160;kernel.Register(&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;AllTypes.Pick().&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;FromAssembly(GetType().Assembly).&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;WithService.FirstInterface().&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//regardless&amp;#160;of&amp;#160;naming&amp;#160;first&amp;#160;interface&amp;#160;is&amp;#160;listed&amp;#160;as&amp;#160;service&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;Configure(c=&amp;gt;c.LifeStyle.Transient));&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;I changed this to the what I thought was the StructureMap equivalent:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:d79dfce8-420e-4afc-b0e8-5a8c1c8453d4" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&amp;#160;var&amp;#160;container&amp;#160;=&amp;#160;&lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&amp;#160;Container(registry&amp;#160;=&amp;gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;registry.Scan(x&amp;#160;=&amp;gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;x.TheCallingAssembly();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;x.With&amp;lt;DefaultConventionScanner&amp;gt;();&amp;#160;&lt;span style="color:#008000"&gt;//does&amp;#160;NOT&amp;#160;configure&amp;#160;the&amp;#160;first&amp;#160;service&amp;#160;interface&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;);&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;);&lt;br/&gt;
container.SetDefault(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IReportFactory),&amp;#160;&lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&amp;#160;ConfiguredInstance(factory));&amp;#160;&lt;span style="color:#008000"&gt;//specific&amp;#160;implemenation&lt;br/&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;Ok so I ran my code and nearly none of my classes were registered only interfaces and classes that were in a pattern like ISpecFinder/SpecFinder.&amp;#160; Looking at SM’s site this is actually expected behavior, and I was not able to find anything that would work the same way as I was used to. I’m not personally a fan of naming interfaces exactly like class names, so after looking around a bit at my options with SM and a brief perusal of Windsor’s source, I used StructureMap’s extensibility to come up with the following:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:2bf7e225-5f44-4a49-ad18-f2f16da28da5" class="wlWriterEditableSmartContent"&gt;&lt;div style="font-family:consolas,lucida console,courier,monospace"&gt;
&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af"&gt;FirstInterfaceConvention&lt;/span&gt;&amp;#160;:&amp;#160;TypeRules,ITypeScanner&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;void&lt;/span&gt;&amp;#160;Process(Type&amp;#160;type,&amp;#160;PluginGraph&amp;#160;graph)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;if&lt;/span&gt;&amp;#160;(!IsConcrete(type))&amp;#160;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt;;&amp;#160;&amp;#160;&lt;span style="color:#008000"&gt;//only&amp;#160;works&amp;#160;on&amp;#160;concrete&amp;#160;types&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;firstinterface&amp;#160;=&amp;#160;type.GetInterfaces().FirstOrDefault();&amp;#160;&lt;span style="color:#008000"&gt;//grabs&amp;#160;first&amp;#160;interface&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;if&lt;/span&gt;(firstinterface!=&lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;graph.AddType(firstinterface,&amp;#160;type);&amp;#160;&lt;span style="color:#008000"&gt;//registers&amp;#160;type&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;graph.AddType(type);&amp;#160;&lt;span style="color:#008000"&gt;//adds&amp;#160;concrete&amp;#160;types&amp;#160;with&amp;#160;no&amp;#160;interfaces&lt;br/&gt;
&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af"&gt;IoCConfig&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:#0000ff"&gt;virtual&lt;/span&gt;&amp;#160;ISpecRunner&amp;#160;InitializeRunner(Type&amp;#160;factory)&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var&amp;#160;container&amp;#160;=&amp;#160;&lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&amp;#160;Container(x=&amp;gt;&amp;#160;x.Scan(&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;y=&amp;gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;{&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;y.TheCallingAssembly();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;y.With&amp;lt;FirstInterfaceConvention&amp;gt;();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;));&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;container.SetDefault(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(IReportFactory),&amp;#160;&lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&amp;#160;ConfiguredInstance(factory));&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br/&gt;
&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;return&lt;/span&gt;&amp;#160;container.GetInstance&amp;lt;ISpecRunner&amp;gt;();&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style="color:#0000ff"&gt;}&lt;/span&gt;&lt;br/&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;and perfecto!&amp;#160; Everything now works as it did before and I was happy that something that wasn’t supported out of the box was so very simple to add myself. Finally, SpecMaker now appears to be working in mono and is nearing a release for me which I will share shortly. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Windsor+style+convention+over+configuration+in+StructureMap&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f07%2fwindsor-style-convention-over-configuration-in-structuremap.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f08%2f07%2fwindsor-style-convention-over-configuration-in-structuremap.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=23527" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Spec/default.aspx">Spec</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Castle/default.aspx">Castle</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/SpecMaker/default.aspx">SpecMaker</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/StructureMap/default.aspx">StructureMap</category></item><item><title>Discussion: Mentoring, Knowledge Transfer and Different Styles Of Learning</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/07/16/discussion-mentoring-knowledge-transfer-and-different-styles-of-learning.aspx</link><pubDate>Fri, 17 Jul 2009 00:06:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:23046</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=23046</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/07/16/discussion-mentoring-knowledge-transfer-and-different-styles-of-learning.aspx#comments</comments><description>&lt;p&gt;I&amp;rsquo;ve been very fortunate that for most of my adult life, even before I got into tech I&amp;rsquo;ve been &amp;ldquo;the boss&amp;rdquo;, and had gobs of mentoring opportunities. I enjoy it and more importantly I know I will have a greater effect for my company&amp;#39;s growth through teaching than I would by solely focusing on my advancement.&lt;/p&gt;
&lt;p&gt;My students have been visual learners, &amp;ldquo;doing&amp;rdquo; learners, audio learners, those that learn by rote memorization with photographic memories, &amp;ldquo;theorists&amp;rdquo; that are fascinated by the theory of things far more than the practice, and those that can&amp;rsquo;t memorize anything unless they see an entire system in place. Each type or combination needs to have information presented in different ways.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t even remotely pretend to know MOST of the answers here, in fact I&amp;rsquo;ll frankly admit there are just some types of people I&amp;rsquo;ve mentored unsuccessfully despite much effort on my part and trying different tactics over many years. &lt;/p&gt;
&lt;p&gt;The best results have come with any &amp;ldquo;system&amp;rdquo; based learners (theoretical or practical), particularly those of a &amp;ldquo;doing&amp;rdquo; bent.&amp;nbsp; However, that is less me and more them. People like that just need to be thrown into a situation and given small amounts of guidance, encouragement, a gob of reference material (not tutorials, reference only!) and they take off and explode. Really, you just need to give people like these work to do and get out of their way so they feel free to grow.&lt;/p&gt;
&lt;p&gt;Visual rote learners, however are the end of me. I&amp;rsquo;ve had several work for me at this point and I&amp;rsquo;m at a loss .&amp;nbsp; I can draw diagrams all day long for them, show them examples, try and give them a number of examples themselves to do, and the minute they get one step off track they&amp;rsquo;re completely lost.&amp;nbsp; I&amp;rsquo;ve tried going into great depth systems wise, answering and demoing any questions they have, teach them the basics of deductive reasoning and troubleshooting, on and on and on.&amp;nbsp; On average I spend 5 times as long with them and I never get anywhere near the success level I do with other types of learners.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m beginning to believe I&amp;rsquo;m just on a fools errand. If there is a way to inspire visual rote learners into becoming dynamic problem solvers, I certainly do not have the skill set to do so.&lt;/p&gt;
&lt;p&gt;Anyone out there have any particular success mentoring those that don&amp;rsquo;t learn by &amp;ldquo;trying&amp;rdquo; things out, and don&amp;rsquo;t have to understand a whole complete system to begin work?&amp;nbsp; What tactics did you use? Did you just assume a slower trajectory but take them through the same material as the faster students? Did you have to resort to &lt;a href="http://www.lostechies.com/blogs/joe_ocampo/default.aspx" target="_blank"&gt;AgileJoe&lt;/a&gt; like Jedi Mind tricks?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m convinced there is a way to reach the vast majority of &amp;quot;struggling&amp;quot; technical people and turn them into at least respectable problem solvers and adequate developers/techs/whatever. I had my own struggles with learning until I got into my mid 20&amp;rsquo;s, and I was able to figure out what worked for me.&amp;nbsp; Pains me to see others in the same boat I was in and I&amp;rsquo;ve so far been unable to help a decent percentage of my past students.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Discussion%3a+Mentoring%2c+Knowledge+Transfer+and+Different+Styles+Of+Learning&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f07%2f16%2fdiscussion-mentoring-knowledge-transfer-and-different-styles-of-learning.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f07%2f16%2fdiscussion-mentoring-knowledge-transfer-and-different-styles-of-learning.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=23046" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Learning/default.aspx">Learning</category></item><item><title>Lessons From My First Attempt At Bringing Agile Into A Non-Agile shop.</title><link>http://www.lostechies.com/blogs/rssvihla/archive/2009/07/12/lessons-from-my-first-attempt-at-bringing-agile-into-a-non-agile-shop.aspx</link><pubDate>Sun, 12 Jul 2009 07:06:08 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22810</guid><dc:creator>Ryan Svihla</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/rssvihla/rsscomments.aspx?PostID=22810</wfw:commentRss><comments>http://www.lostechies.com/blogs/rssvihla/archive/2009/07/12/lessons-from-my-first-attempt-at-bringing-agile-into-a-non-agile-shop.aspx#comments</comments><description>&lt;p&gt;Since I’m moving on from my current employer I figure now is a great time to share my post-mortem of my time there, specifically what worked, what didn’t and what did I learn.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Iterations Of Any Length&lt;/h3&gt;  &lt;p&gt;We tried 3 weeks, 2 weeks, 1 week, monthly and eventually just sort of tossed the system out all together as our team got shrunk from 5 to 2.&amp;#160; We did find get a fairly desirable result ultimately but more on that later.&amp;#160; Ultimately our problem was especially as we got smaller, dealing with our “particular” realities made iterations tend to fall apart, we were spending a fair amount of time trying to torture ever more atomic stories together.&amp;#160; Cutting iterations out all together and focusing on features being completed was MUCH more time effective for us.&lt;/p&gt;  &lt;h3&gt;Continuous Integration &lt;/h3&gt;  &lt;p&gt;We had 3 different build servers at various points. All worked well, and our scripts were build server agnostic enough to not take long to switch over. There was a bit of a learning curve with some projects and the build system (modular dll’s and app domains especially).&amp;#160; While in the end this worked well for our purposes, I failed in sharing the knowledge here, and never figured out how to get other members of the team to get up to speed on the entire build server concept .&amp;#160; &lt;/p&gt;  &lt;p&gt;Note: oddly no “build applet” was nearly as effective at letting people know the build failed as sending them an email automatically on failure. &lt;/p&gt;  &lt;h3&gt;TDD, BDD And Unit Testing&lt;/h3&gt;  &lt;p&gt;Very mixed bag here. I was successful in getting the concept of unit testing in, but not TDD.&amp;#160; However, our tests still are not totally flexible, and the training to do that is significant (creates dependencies on a fair amount of knowledge not specifically related to testing).&amp;#160; For my part it honestly took me a year to be able to write a test that was not brittle.&amp;#160; &lt;/p&gt;  &lt;p&gt;I’m still a bit stumped how to get a typically trained Microsoft developer team to really dive into the concept of TDD, “writing the code you want” was met with blank stares.&amp;#160; Data driven mindset was maintained to some degree throughout my time there.&lt;/p&gt;  &lt;p&gt;BDD took me awhile to get something I felt comfortable with so I don’t think I trained with the proper approach. I emphasized specification and example a lot and for some reason this lead to everyone striving for functional tests.&amp;#160; &lt;/p&gt;  &lt;p&gt;Finally, handing customers spec results was somewhat helpful. Still had some things “be fine” then “that’s not what I meant”, but it still cut down the amount of misunderstanding.&lt;/p&gt;  &lt;h3&gt;SOLID Principles&lt;/h3&gt;  &lt;p&gt;This was the easiest thing overall. DIP and IoC was resisted heavily at first, but it was not much effort to come up with scenarios where it was patently obvious how much more flexible code became.&amp;#160; I focused a ton of “different data sources” since we have a number of api’s we deal with that gave me the buy-in I needed.&lt;/p&gt;  &lt;p&gt;SRP took a bit but once they got it they got it big (almost too well). Ultimately, I think the dev’s enjoyed having “another box to check off” as they finished each class.&amp;#160; Resharper training also helped cut down the time to make classes and methods I believed this also had a role in SRP adoption. &lt;/p&gt;  &lt;p&gt;OCP came with focusing on IoC and DiP so heavily.&lt;/p&gt;  &lt;p&gt;LSP only came up occasionally since we tended to have a lot of small classes.&lt;/p&gt;  &lt;h3&gt;YAGNI And DRY&lt;/h3&gt;  &lt;p&gt;YAGNI - Always fought this myself, and correspondingly my team struggled with both as well.&amp;#160; YAGNI by the end started to work just because I began stripping out all extra requirements full stop, and immediately stopping any development when “extra” features were added out of the blue by an enthusiastic developer. This took a heavy hand and vigilance, and convincing was less the issue than fighting habits developed over years.&lt;/p&gt;  &lt;p&gt;DRY – Was especially rampant in our test code, and we had our bits of duplication across projects and different developers. Like our YAGNI violations I think this was years of habits holding us back.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Automated Acceptance Tests&lt;/h3&gt;  &lt;p&gt;Never got close. Not enough stakeholders were interested, the training on acceptance tests ran into the same problem I had with build scripts that no one understood systems enough to make this function properly unless I was involved heavily, and then breaks also required my involvement. Finally scrapped them and moved to specs and manual acceptance testing by the stakeholders that cared about it in the way that they cared about it.&lt;/p&gt;  &lt;h3&gt;Release Frequently Release Often&lt;/h3&gt;  &lt;p&gt;The more we released the better it worked for us. For us there was a clear link between stakeholder satisfaction and frequent releases (10+ some weeks). I have a few theories about this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;We had stakeholders with various levels of comfort on their subject matter. Domain experts that knew everything about their domain did not need as much “final product” feedback as some others, who really were only happy when they saw the end product after every request. &lt;/li&gt;    &lt;li&gt;Most of our projects had few moving parts. The tendency of past development seems to have been drawn to complexity, even when the raw domain didn’t need it.&amp;#160; Simple projects can be released more often when less moving parts are there to break.&lt;/li&gt;    &lt;li&gt;Our stakeholders seemed to be far more results driven than UI driven. We seemed to attract a lot of process driven people who were content with having a lousy limited UI as long as the file went out in the correct format. We could again release more often with a stubbed in UI without any real penalty, as ultimately they just wanted at least one front to back business case working.&lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Summary&lt;/h3&gt;  &lt;p&gt;There is more that I’m sure that I’m missing that may be useful. In the end, I was disappointed in my attempt to move the shop to an Agile concept only because I was not able to spread the knowledge effectively. My inexperience at the time in Agile myself made it rougher on everyone else trying to learn from me.&lt;/p&gt;  &lt;p&gt;If I had to do it over again, I’d focus on SOLID, YAGNI, DRY and training a systems administrator in build scripts (it’s just a hard skill set for the average MS developer), and of course release often. If I had focused on these things first the immediate dividends would have been far larger.&amp;#160; Once they had the necessary engineering credentials, TDD would have been less of a time sink, and maybe we’d have had the discipline for Iterations.&amp;#160; Someday I hope to have the opportunity to build an Agile team from scratch again.&amp;#160; I’m grateful to my employer and my co-workers who gave me the opportunity to try and advance things forward (which we did, just not as far as I would have liked).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Lessons+From+My+First+Attempt+At+Bringing+Agile+Into+A+Non-Agile+shop.&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f07%2f12%2flessons-from-my-first-attempt-at-bringing-agile-into-a-non-agile-shop.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2frssvihla%2farchive%2f2009%2f07%2f12%2flessons-from-my-first-attempt-at-bringing-agile-into-a-non-agile-shop.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22810" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Lean/default.aspx">Lean</category><category domain="http://www.lostechies.com/blogs/rssvihla/archive/tags/Agile/default.aspx">Agile</category></item></channel></rss>