<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7349901047715470998</id><updated>2012-01-11T00:39:55.138-08:00</updated><category term='sloppycode'/><category term='simplicity'/><category term='thankgoditsover'/><category term='hiro ioc codeproject dotnet'/><category term='linfu aop redesign notes dotnet'/><category term='mono.cecil'/><category term='dlr'/><category term='hiro ioc codeproject dynamic'/><category term='enoughisenough'/><category term='refactoring'/><category term='vacation'/><category term='dynamiclanguages'/><category term='hiro linfu ioc dotnet codeproject'/><category term='general'/><category term='writersblock'/><category term='linfu adaptiveobjectmodels dotnet myxaml dynamicobject reflection'/><category term='writethisblock'/><category term='mvc mvp mvwithoutthep patterns eureka'/><category term='dbc'/><category term='notinventedhere'/><category term='wishlist'/><category term='cecil'/><category term='ohthehumanity'/><category term='csharp'/><category term='ceciltheuglywife'/><category term='linfu'/><category term='clr'/><category term='futurefeatures'/><category term='hiro ioc codeproject'/><category term='orm'/><category term='kiss'/><category term='design'/><category term='linfu aop notes dotnet'/><category term='nottheoldhagagain'/><category term='whew aop linfu thankgoditstuesday'/><category term='reinventingthewheel prototypes aop linfu redesign design'/><category term='nih'/><category term='linfu redesign rewrite versiontwo'/><category term='linfu ioc versiontwo csharp'/><category term='mono'/><category term='eureka linfu aop byjovewehaveit greatscott omg dotnet'/><category term='architecture'/><category term='dotnet'/><category term='writing'/><category term='linfu ioc versiontwo design dotnet csharp'/><category term='codeproject'/><category term='reinventingthewheel prototypes aop linfu'/><category term='ide'/><title type='text'>Philip Laureano's Development Blog</title><subtitle type='html'>01001001 00100000 01100010 01100101 01101100 01101001 01100101 01110110 01100101 00101100 00100000 01110100 01101000 01100101 01110010 01100101 01100110 01101111 01110010 01100101 00101100 00100000 01001001 00100000 01100010 01100101 01100011 01101111 01101101 01100101 00101110</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>45</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-5133624147200476013</id><published>2011-05-08T00:59:00.000-07:00</published><updated>2011-05-08T00:59:18.763-07:00</updated><title type='text'>Introduction to IL Rewriting with Cecil, Part 1–Rewriting FizzBuzz and the Art of Redirecting Method Calls</title><content type='html'>&lt;p&gt;&lt;a href="http://lh4.ggpht.com/__BgjkW_AfhY/TcZMptdTNtI/AAAAAAAAAOM/DFn_h-VkBlw/s1600-h/lesson1%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="lesson1" border="0" alt="lesson1" src="http://lh3.ggpht.com/__BgjkW_AfhY/TcZMqYG3uBI/AAAAAAAAAOQ/eGDCq85GGVg/lesson1_thumb%5B1%5D.png?imgmax=800" width="485" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h6&gt;&lt;/h6&gt;&lt;h6&gt;The simplest possible code example that anyone can learn from.&lt;/h6&gt;&lt;h4&gt;Introduction&lt;/h4&gt;&lt;p&gt;When I first started learning IL rewriting and &lt;a href="https://github.com/jbevain/cecil"&gt;Cecil&lt;/a&gt; about several years ago, one of the difficulties that I struggled with was the fact that there were &lt;a href="http://stackoverflow.com/questions/1513319/mono-cecil-documentation-and-tutorials"&gt;very few practical examples&lt;/a&gt; on how to take an existing assembly and modify it at runtime. In many ways, I was stranded in heavily undocumented territory, and needless to say, this lack of documentation made it very difficult to learn how to do anything useful with Cecil.&lt;/p&gt;&lt;h4&gt;Meanwhile, in the Year 2011…&lt;/h4&gt;&lt;p&gt;It’s now 2011, and I think it’s safe to say that for many people, IL rewriting (much less Cecil) is still a &lt;a href="http://ayende.com/Blog/archive/2007/05/30/IL-Weaving--Mystery-wrapped-in-an-Enigma-containing-Frustration.aspx"&gt;“big mystery wrapped in an enigma containing frustration”&lt;/a&gt;. Indeed, Cecil is an incredible library that can let you do some incredible things, but at the same time, it can be very frustrating since the learning curve is still steep and there are still no practical guides for using it. As a user, there must be some sample code out there that shows how to do the most basic tasks with Cecil, right?&lt;/p&gt;&lt;h4&gt;Establishing the Feedback Loop&lt;/h4&gt;&lt;p&gt;In order to learn any skill (such as IL rewriting), we need to establish a simple feedback loop that allows users to easily experiment with the tools they are given so that they know:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What went wrong if it doesn’t work &lt;/li&gt;&lt;li&gt;Where to fix it if it breaks &lt;/li&gt;&lt;li&gt;How to see the results of their experiments without getting mired in the implementation details of the tests themselves &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In this case, we’ll need to set up a basic environment that will let users experiment and learn how to modify assemblies at runtime with Cecil. We will need:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A test fixture that loads a sample assembly and gives users the chance to modify it before reloading the modified assembly into memory (An NUnit base fixture) &lt;/li&gt;&lt;li&gt;A way to display/diagnose any invalid assembly errors that occur due to making changes to the original assembly (PEVerify) &lt;/li&gt;&lt;li&gt;To make it easy to change so that we can experiment with different approaches to modifying IL, thus “closing” the feedback loop &lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;Lost in Bytecode&lt;/h4&gt;&lt;p&gt;Given these requirements, where would we even begin? It’s not every day that one decides to randomly parse .NET assemblies and learn how to change the underlying bytecode that ultimately defines their behavior. This can seem like a daunting task for even the most intelligent of budding interlopers, but fortunately for my readers, most of the work has already been done for you &lt;a href="https://github.com/philiplaureano/Cecil.Tutorials"&gt;in these examples&lt;/a&gt;. All you need to do is sit back and scroll down the page, as I proceed to tell you the “ins” and “outs” about Cecil, and the practical lessons learned from rewriting IL. With that in mind, let’s get started!&lt;/p&gt;&lt;h4&gt;&lt;/h4&gt;&lt;h4&gt;A WriteLine for Another WriteLine&lt;/h4&gt;&lt;p&gt;One of the simplest things that you can possibly do with Cecil is to swap a single static method call for another static method call with the same parameters and the same return type. (It’s a fairly simple operation since both methods have the same signature, and you don’t need to add any additional instructions to make it happen). In this case, I opted to swap all calls to Console.WriteLine() with calls to FakeConsole.WriteLine():&lt;/p&gt;&lt;script src="https://gist.github.com/961185.js?file=gistfile1.cs"&gt;&lt;/script&gt;  &lt;p&gt;As you can see from the example above, I used a simple LINQ query to identify all the call instructions that needed to be modified. More experienced Cecil users will probably notice that I decided to rewrite all method calls to point to FakeConsole.WriteLine() instead of individually checking to make sure that the method call I was replacing was indeed Console.WriteLine(). Indeed, that was an intentional move, given that the FizzBuzz.Print() method doesn’t make any other external calls to any other methods besides Console.WriteLine(). &lt;/p&gt;&lt;p&gt;Assuming that I somehow created an instruction that caused an invalid modified assembly, however, how would I be able to know what went wrong, much less know how to fix it?&lt;/p&gt;&lt;h4&gt;PEVerify, how do I love &lt;strike&gt;and hate&lt;/strike&gt; thee…&lt;/h4&gt;&lt;p&gt;As it turns out, there is &lt;a href="http://msdn.microsoft.com/en-us/library/62bwd2yd(v=vs.80).aspx"&gt;a tool called PEVerify.exe&lt;/a&gt; that can tell you whether or not the assemblies that you modify with Cecil are valid or invalid. For example, if I were to remove all the IL instructions out of the FizzBuzz.Print() method, PEVerify would give me the following error message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/__BgjkW_AfhY/TcZMq1E6y3I/AAAAAAAAAOU/15WQkC-UwR4/s1600-h/peverify1%5B4%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="peverify1" border="0" alt="peverify1" src="http://lh5.ggpht.com/__BgjkW_AfhY/TcZMroOoeYI/AAAAAAAAAOY/TcE3hpjaVuY/peverify1_thumb%5B2%5D.png?imgmax=800" width="485" height="156" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h6&gt;(Believe me, it’s much prettier when it’s zoomed out)&lt;/h6&gt;&lt;p&gt;PEVerify will examine any given assembly and be able to tell you whether or not the compiler (or in this case, &lt;em&gt;you&lt;/em&gt;, the human compiler) made any mistakes in creating the assembly. It can be a very useful tool, and that’s why I modified the sample test fixture to run PEVerify right after the user modifies the sample assembly. If you don’t already have PEVerify installed, make sure you &lt;a href="http://stackoverflow.com/questions/1915182/where-can-i-download-peverify-exe-tool"&gt;download it&lt;/a&gt; and configure the Lesson1 app.config file to point to where PEVerify is installed:&lt;/p&gt;&lt;script src="https://gist.github.com/961203.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;br /&gt;Once PEVerify has been configured as part of the tests, the rest is up to your imagination.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Exploring Method Replacement and Beyond&lt;/h4&gt;&lt;p&gt;Now that the basic IL rewriting setup has been laid out for you, the onus is on you to explore the possibilities with Cecil and IL rewriting, even if it means that you have to start with some small, basic steps. In the next installment in this series, I’ll show you how to use PEVerify and Cecil to keep the stack balanced so that you can do things like swap static method calls for instance method calls, and even do things like install runtime hooks so you can change your code as your application is running. Stay tuned!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-5133624147200476013?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/5133624147200476013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5133624147200476013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5133624147200476013'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html' title='Introduction to IL Rewriting with Cecil, Part 1–Rewriting FizzBuzz and the Art of Redirecting Method Calls'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/__BgjkW_AfhY/TcZMqYG3uBI/AAAAAAAAAOQ/eGDCq85GGVg/s72-c/lesson1_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-6733261898992208376</id><published>2011-05-03T18:18:00.000-07:00</published><updated>2011-05-03T21:08:28.704-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codeproject'/><title type='text'>Dynamically Intercepting Thrown Exceptions with LinFu.AOP 2.0</title><content type='html'>&lt;p&gt;&lt;a href="http://lh6.ggpht.com/__BgjkW_AfhY/TcCklRZIVLI/AAAAAAAAAN4/0QTo611dmt0/s1600-h/exception%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="exception" border="0" alt="exception" src="http://lh5.ggpht.com/__BgjkW_AfhY/TcCkmRgPliI/AAAAAAAAAN8/lSXHZS2VGvQ/exception_thumb%5B2%5D.jpg?imgmax=800" width="493" height="263" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h6&gt;&lt;font style="font-weight: normal"&gt;A screenshot of LinFu dynamically catching a thrown exception.&lt;/font&gt;&lt;/h6&gt;&lt;h4&gt;On Error, Resume Interception&lt;/h4&gt;&lt;p&gt;Another useful thing that LinFu.AOP allows you to do is to intercept (and rethrow) exceptions within your applications at runtime. LinFu makes it so easy, in fact, that all you have to do is add the following lines to your CSProj file:&lt;/p&gt;&lt;script src="https://gist.github.com/954549.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;h4&gt;Exceptionally Simple&lt;/h4&gt;To use LinFu.AOP's dynamic exception handling capabilities, all you need to do is make the following call to handle all exceptions being thrown in your application: &lt;br /&gt;&lt;script src="https://gist.github.com/954554.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Try/Catch Me, If You Can&lt;/h4&gt;The call to ExceptionHandlerRegistry.SetHandler tells LinFu to hook the SampleExceptionHandler into your application so that all exceptions that will be thrown will automatically be handled by the given exception handler. Under normal circumstances (where interception is disabled), the call to account.Deposit() will cause the app to crash, but &lt;a href="http://github.com/philiplaureano/LinFu.AOP.Examples/tree/CatchingThrownExceptions"&gt;as this example shows&lt;/a&gt;, LinFu.AOP was able to intercept the thrown exception before it could crash the rest of the app.&lt;p&gt;&lt;/P&gt;What makes this even more interesting, however, is the IExceptionHandlerInfo instance that describes the context from which the exception was thrown:&lt;br /&gt;&lt;script src="https://gist.github.com/954572.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;More Information Than You Can Throw An Exception At&lt;/h4&gt;&lt;br /&gt;The IExceptionHandlerInfo interface has enough information to describe the method that caused the exception, as well as having properties such as ShouldSkipRethrow that allow you to decide whether or not LinFu should just swallow the exception and keep running the program as if an exception was never thrown. The ReturnValue property, in turn, allows you to alter the return value of a given method in case you want to resume the method and provide an alternate return value as if no exceptions were ever thrown. &lt;br /&gt;&lt;br /&gt;As you can see, LinFu.AOP makes it really easy to transparently handle exceptions in your applications, and if this post saves at least a few developers a few headaches from having to manually diagnose their applications, then I'd consider it to be a gratifying success.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;EDIT: You can get the code examples for LinFu.AOP's dynamic exception handling &lt;a href="http://github.com/philiplaureano/LinFu.AOP.Examples/tree/CatchingThrownExceptions"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-6733261898992208376?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/6733261898992208376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/05/dynamically-intercepting-thrown.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6733261898992208376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6733261898992208376'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/05/dynamically-intercepting-thrown.html' title='Dynamically Intercepting Thrown Exceptions with LinFu.AOP 2.0'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/__BgjkW_AfhY/TcCkmRgPliI/AAAAAAAAAN8/lSXHZS2VGvQ/s72-c/exception_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-683302266063776539</id><published>2011-04-27T18:30:00.001-07:00</published><updated>2011-05-03T21:08:41.874-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codeproject'/><title type='text'>Intercepting Console.WriteLine and Other Third-Party Method Calls with LinFu.AOP 2.0</title><content type='html'>&lt;a href="http://lh3.ggpht.com/__BgjkW_AfhY/TbjDLCN6W-I/AAAAAAAAANo/QBT-uVrkmHs/s1600-h/ConsoleInterceptor5.png"&gt;&lt;img alt="ConsoleInterceptor" border="0" height="247" src="http://lh4.ggpht.com/__BgjkW_AfhY/TbjDLpJJ_NI/AAAAAAAAANs/u6DSMW2IXXo/ConsoleInterceptor_thumb3.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ConsoleInterceptor" width="448" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;Worth a thousand words&lt;/h4&gt;In case you are wondering, yes, that is a screenshot of LinFu.AOP intercepting calls to Console.WriteLine() at runtime.&lt;br /&gt;One of the more useful things that LinFu.AOP can do is intercept calls to third-party assemblies that aren’t necessarily under your control. In fact, LinFu makes it so easy that all you have to do to make the interception happen is add the reference to LinFu like the following lines to your CSProj file just like I did with my SampleLibrary.csproj file:&lt;br /&gt;&lt;span style="color: teal;"&gt;   &lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="csharpcode"&gt;&lt;span style="color: teal;"&gt;&lt;span style="color: black;"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;br /&gt;&amp;lt;PostWeaveTaskLocation&amp;gt;$(MSBuildProjectDirectory)\$(OutputPath)\..\..\..\lib\LinFu.Core.dll&amp;lt;/PostWeaveTaskLocation&amp;gt;&lt;br /&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;br /&gt;&amp;lt;UsingTask TaskName="PostWeaveTask" AssemblyFile="$(PostWeaveTaskLocation)" /&amp;gt;&lt;br /&gt;&amp;lt;Target Name="AfterBuild"&amp;gt;&lt;br /&gt;&amp;lt;PostWeaveTask TargetFile="$(MSBuildProjectDirectory)\$(OutputPath)$(MSBuildProjectName).dll" InterceptAllMethodCalls="true" /&amp;gt;&lt;br /&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: teal;"&gt;&lt;br /&gt;&lt;h4&gt;&lt;span style="color: #333333;"&gt;‘Automagically’ Delicious&lt;/span&gt;&lt;/h4&gt;&lt;div&gt;&lt;span style="color: black; font-family: Verdana;"&gt;Once you reload and rebuild the solution, LinFu.AOP will automatically modify your code after the build runs so that you can intercept it at runtime. LinFu does this by adding hooks to your code so you can change it as the program is running. In this case, I casted the modified BankAccount class to an IModifiableType instance so that I could add my custom ConsoleInterceptor instance:&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="color: teal;"&gt;&lt;span style="color: black;"&gt;&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;// Create the BankAccount class just like normal...&lt;/pre&gt;&lt;pre class="brush: csharp;"&gt;var account = new BankAccount(100);&lt;/pre&gt;&lt;pre class="brush: csharp;"&gt;// Notice how LinFu.AOP automatically implements IModifiableType so you can intercept/replace method calls at runtime&lt;br /&gt;var modifiableType = account as IModifiableType;&lt;br /&gt;if (modifiableType != null)&lt;br /&gt;modifiableType.MethodCallReplacementProvider = new WriteLineMethodReplacementProvider();&lt;br /&gt;&lt;br /&gt;account.Deposit(100);&lt;/pre&gt;The WriteLineMethodReplacementProvider class, in turn, determines the method calls that should be intercepted at runtime:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class WriteLineMethodReplacementProvider : IMethodReplacementProvider&lt;br /&gt;{&lt;br /&gt;public bool CanReplace(object host, IInvocationInfo info)&lt;br /&gt;{&lt;br /&gt;var declaringType = info.TargetMethod.DeclaringType;&lt;br /&gt;if (declaringType != typeof(System.Console))&lt;br /&gt;return false;&lt;br /&gt;&lt;br /&gt;// We're only interested in replacing Console.WriteLine()&lt;br /&gt;var targetMethod = info.TargetMethod;&lt;br /&gt;return targetMethod.Name == "WriteLine";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IInterceptor GetMethodReplacement(object host, IInvocationInfo info)&lt;br /&gt;{&lt;br /&gt;return new ConsoleInterceptor();&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;h4&gt;Choosing which methods to intercept&lt;/h4&gt;As you can see from the example above, this class ensures that only calls to Console.WriteLine() are ever intercepted. The ConsoleInterceptor itself is responsible for replacing and intercepting the Console.WriteLine() method itself:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class ConsoleInterceptor : IInterceptor&lt;br /&gt;{&lt;br /&gt;public object Intercept(IInvocationInfo info)&lt;br /&gt;{&lt;br /&gt;var targetType = info.TargetMethod.DeclaringType;&lt;br /&gt;var target = info.Target;&lt;br /&gt;var targetMethod = info.TargetMethod;&lt;br /&gt;var arguments = info.Arguments;&lt;br /&gt;&lt;br /&gt;Console.WriteLine("Intercepted method named '{0}'", targetMethod.Name);&lt;br /&gt;&lt;br /&gt;// Call the original WriteLine method&lt;br /&gt;targetMethod.Invoke(null, arguments);&lt;br /&gt;&lt;br /&gt;// Console.WriteLine doesn't have a return value so it's OK to return null)&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;The most interesting part about the code example is how LinFu.AOP adds the method call hooks without touching a single line of the source code. All of the IL rewriting is done behind the scenes so you won’t have to worry about the gory details of using an AOP framework in your legacy code. The beauty of this approach is that it allows you to intercept any method call, even if that method call is a part of the .NET base class libraries. &lt;br /&gt;You can find the LinFu.AOP.Examples library &lt;a href="https://github.com/philiplaureano/LinFu.AOP.Examples"&gt;here at Github&lt;/a&gt;.&lt;br /&gt;NOTE: Please intercept BCL method calls responsibly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-683302266063776539?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/683302266063776539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/intercepting-consolewriteline-and-other.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/683302266063776539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/683302266063776539'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/intercepting-consolewriteline-and-other.html' title='Intercepting Console.WriteLine and Other Third-Party Method Calls with LinFu.AOP 2.0'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/__BgjkW_AfhY/TbjDLpJJ_NI/AAAAAAAAANs/u6DSMW2IXXo/s72-c/ConsoleInterceptor_thumb3.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-39650941617513329</id><published>2011-04-27T02:48:00.001-07:00</published><updated>2011-05-03T21:09:02.217-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codeproject'/><title type='text'>Beyond Duck Typing with LinFu.DynamicObject: Creating Types that can Change at Runtime</title><content type='html'>&lt;h4&gt;A Post-Easter Egg&lt;/h4&gt;One of the hidden features that LinFu.DynamicObject has is the ability to dynamically add properties and methods to itself using a shared type definition at runtime. In other words, you can have two or more LinFu.DynamicObject instances share the same DynamicType, and any changes you make to that type will be propagated to all LinFu.DynamicObject instances that share that same type:&lt;br /&gt;&lt;pre&gt;using LinFu.Reflection.Extensions;&lt;br /&gt;using NUnit.Framework;&lt;br /&gt;&lt;br /&gt;namespace LinFu.Reflection.Tests&lt;br /&gt;{&lt;br /&gt;[TestFixture]&lt;br /&gt;public class DynamicTypeTests&lt;br /&gt;{&lt;br /&gt;[Test]&lt;br /&gt;public void ShouldBeAbleToShareTheSameDynamicType()&lt;br /&gt;{&lt;br /&gt;var typeSpec = new TypeSpec() { Name = "Person" };&lt;br /&gt;&lt;br /&gt;// Add an age property &lt;br /&gt;typeSpec.AddProperty("Age", typeof(int));&lt;br /&gt;&lt;br /&gt;// Attach the DynamicType named 'Person' to a bunch of dynamic objects&lt;br /&gt;var personType = new DynamicType(typeSpec);&lt;br /&gt;var first = new DynamicObject();&lt;br /&gt;var second = new DynamicObject();&lt;br /&gt;&lt;br /&gt;first += personType;&lt;br /&gt;second += personType;&lt;br /&gt;&lt;br /&gt;// Use both objects as persons&lt;br /&gt;IPerson firstPerson = first.CreateDuck&amp;lt;IPerson&amp;gt;();&lt;br /&gt;IPerson secondPerson = second.CreateDuck&amp;lt;IPerson&amp;gt;();&lt;br /&gt;&lt;br /&gt;firstPerson.Age = 18;&lt;br /&gt;secondPerson.Age = 21;&lt;br /&gt;&lt;br /&gt;Assert.AreEqual(18, firstPerson.Age);&lt;br /&gt;Assert.AreEqual(21, secondPerson.Age);&lt;br /&gt;&lt;br /&gt;// Change the type so that it supports the INameable interface&lt;br /&gt;typeSpec.AddProperty("Name", typeof(string));&lt;br /&gt;INameable firstNameable = first.CreateDuck&amp;lt;INameable&amp;gt;();&lt;br /&gt;INameable secondNameable = second.CreateDuck&amp;lt;INameable&amp;gt;();&lt;br /&gt;&lt;br /&gt;firstNameable.Name = "Foo";&lt;br /&gt;secondNameable.Name = "Bar";&lt;br /&gt;&lt;br /&gt;Assert.AreEqual("Foo", firstNameable.Name);&lt;br /&gt;Assert.AreEqual("Bar", secondNameable.Name);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Evolving Ducks&lt;/h4&gt;Most of the code above is self-explanatory, and the most interesting part about this code is the fact that it has two DynamicObject instances that share the same DynamicType instance. Once the Age property was added to the DynamicType definition, both first and second DynamicObjects automatically ‘inherited’ the additional Age property that was added to the DynamicType at runtime. Another interesting piece of code was the duck typing call to the IPerson interface, which wasn’t possible until after the Age property was added:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// Use both objects as persons&lt;br /&gt;IPerson firstPerson = first.CreateDuck&lt;iperson&gt;();&lt;br /&gt;IPerson secondPerson = second.CreateDuck&lt;iperson&gt;();&lt;br /&gt;&lt;br /&gt;firstPerson.Age = 18;&lt;br /&gt;secondPerson.Age = 21;&lt;br /&gt;&lt;br /&gt;Assert.AreEqual(18, firstPerson.Age);&lt;br /&gt;Assert.AreEqual(21, secondPerson.Age);&lt;/iperson&gt;&lt;/iperson&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see from the example above, LinFu.DynamicObject is smart enough to change its definition every time the attached DynamicType definition changes, and that’s why it was also able to duck type itself to the INameable interface:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// Change the type so that it supports the INameable interface // Change the type so that it supports the INameable interface&lt;br /&gt;            typeSpec.AddProperty("Name", typeof(string));&lt;br /&gt;            INameable firstNameable = first.CreateDuck&amp;lt;INameable&amp;gt;();&lt;br /&gt;            INameable secondNameable = second.CreateDuck&amp;lt;INameable&amp;gt;();&lt;br /&gt;&lt;br /&gt;            firstNameable.Name = "Foo";&lt;br /&gt;            secondNameable.Name = "Bar";&lt;br /&gt;&lt;br /&gt;            Assert.AreEqual("Foo", firstNameable.Name);&lt;br /&gt;            Assert.AreEqual("Bar", secondNameable.Name);&lt;br /&gt;&lt;/pre&gt;Pretty straightforward, isn't it? (LinFu.DynamicObject has had this feature for well over 4 years, but I never got around to &lt;a href="http://github.com/philiplaureano/LinFu.DynamicObject"&gt;publishing it&lt;/a&gt; until now). Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-39650941617513329?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/39650941617513329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/beyond-duck-typing-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/39650941617513329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/39650941617513329'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/beyond-duck-typing-with.html' title='Beyond Duck Typing with LinFu.DynamicObject: Creating Types that can Change at Runtime'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1424244181117874103</id><published>2011-04-25T17:40:00.001-07:00</published><updated>2011-05-03T21:09:18.700-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codeproject'/><title type='text'>Duck Typing with LinFu &amp; C# 4.0’s Dynamic Keyword</title><content type='html'>&lt;h4&gt;The Lame Duck&lt;/h4&gt;&lt;p&gt;When C# 4.0 came out with the &lt;em&gt;dynamic&lt;/em&gt; keyword, I was pretty excited over the prospect of having Ruby-like features finally being baked in to the C# language itself, but as &lt;a href="http://twitter.com/davetchepak"&gt;one of my twitter followers&lt;/a&gt; and friends pointed out in &lt;a href="http://www.davesquared.net/2009/06/dynamic-disappointment.html"&gt;one of their posts from a few years ago&lt;/a&gt;, C# 4.0 still lacks duck typing support, and the .NET BCL doesn’t seem to have anything that could do something similar to the following code:&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; ICanAdd&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Add(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; a, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; b);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SomethingThatAdds&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ICanAdd _adder;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SomethingThatAdds(ICanAdd adder)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;_adder = adder;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; FirstNumber { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; SecondNumber { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; AddNumbers()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _adder.Add(FirstNumber, SecondNumber);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;There has to be some way to construct an object at runtime and map it to an &lt;em&gt;ICanAdd&lt;/em&gt; interface, but the problem is that the current .NET Base Class Libraries don’t seem to have a solution for this problem. As Dave Tchepak pointed out in his post, the following dynamic code will fail miserably at runtime:&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Dynamic : DynamicObject&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Dictionary&amp;lt;String, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; members = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; TrySetMember(SetMemberBinder binder, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;members[binder.Name] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; TryGetMember(GetMemberBinder binder, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; result)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; members.TryGetValue(binder.Name, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; result);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// ..and the test would look like:&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;[Test]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CannotUseDynamicAdderForAnythingUseful()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;dynamic adder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dynamic();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;adder.Add = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt;((first, second) =&amp;gt; first + second);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var somethingThatCanAdd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SomethingThatAdds(adder); &lt;span style="color: #008000"&gt;/* Fails here at runtime */&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;somethingThatCanAdd.FirstNumber = 10;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;somethingThatCanAdd.SecondNumber = 20;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Assert.That(somethingThatCanAdd.AddNumbers(), Is.EqualTo(30));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The problem is that the runtime isn’t smart enough to figure out that there has to be a duck-typing cast to the ICanAdd interface in order to use the &lt;em&gt;SomethingThatCanAdd&lt;/em&gt; class, and that’s where LinFu’s DynamicObject comes in handy.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;If it walks and quacks like a duck, then it’s all good&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="https://github.com/philiplaureano/LinFu.DynamicObject"&gt;LinFu.DynamicObject&lt;/a&gt; is flexible enough that it can let you build object instances at runtime and then ‘strongly’ duck type those object instances to any interface that matches the intended duck type. In this case, we need to find a way to build up something that can map to an &lt;em&gt;ICanAdd&lt;/em&gt; interface instance so that it can be used by the &lt;em&gt;SomethingThatAdds&lt;/em&gt; class:&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;[Test]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CanCreateADynamicAdder()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var adder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicObject();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;CustomDelegate addBody = &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[] args)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; a = (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)args[0];&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; b = (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)args[1];&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; a + b;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Map LinFu's DynamicObject to an ICanAdd interface&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var linfuDynamicObject = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicObject(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var returnType = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var parameterTypes = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;), &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;) };&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;linfuDynamicObject.AddMethod("&lt;span style="color: #8b0000"&gt;Add&lt;/span&gt;", addBody, returnType, parameterTypes);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// If it looks like a duck...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Assert.IsTrue(linfuDynamicObject.LooksLike&amp;lt;ICanAdd&amp;gt;());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// ...then it must be a duck, right?&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;var somethingThatCanAdd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SomethingThatAdds(adder.CreateDuck&amp;lt;ICanAdd&amp;gt;());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;somethingThatCanAdd.FirstNumber = 10;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;somethingThatCanAdd.SecondNumber = 20;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Assert.AreEqual(somethingThatCanAdd.AddNumbers(), 30);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;font face="Verdana"&gt;The call to the &lt;em&gt;DynamicObject.CreateDuck()&lt;/em&gt; method does all the heavy lifting for you so you don’t have to worry about the details of how to make the object behave like a duck. It just works, and that’s the power that LinFu offers.&lt;/font&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;font face="Verdana"&gt;(EDIT: You can grab the source code and examples for LinFu.DynamicObject &lt;a href="https://github.com/philiplaureano/LinFu.DynamicObject"&gt;here at Github&lt;/a&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;font face="Verdana"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9b0dbc35-6901-42e8-9e19-93d9697cdb16" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/linfu" rel="tag"&gt;linfu&lt;/a&gt;,&lt;a href="http://technorati.com/tags/dynamicobject" rel="tag"&gt;dynamicobject&lt;/a&gt;,&lt;a href="http://technorati.com/tags/csharp4" rel="tag"&gt;csharp4&lt;/a&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1424244181117874103?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1424244181117874103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/duck-typing-with-linfu-c-40s-dynamic.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1424244181117874103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1424244181117874103'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/duck-typing-with-linfu-c-40s-dynamic.html' title='Duck Typing with LinFu &amp;amp; C# 4.0’s Dynamic Keyword'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3064656714818020077</id><published>2011-04-24T04:28:00.001-07:00</published><updated>2011-04-24T04:28:42.129-07:00</updated><title type='text'>A CQRS and an AOP expert walk into an Oredev bar…</title><content type='html'>&lt;h4&gt;&lt;a href="http://lh6.ggpht.com/__BgjkW_AfhY/TbQJZ13WwOI/AAAAAAAAANg/XRcG3xwtn8o/s1600-h/5166054200_220bec62b0_b%5B3%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="5166054200_220bec62b0_b" border="0" alt="5166054200_220bec62b0_b" src="http://lh4.ggpht.com/__BgjkW_AfhY/TbQJaUAqvbI/AAAAAAAAANk/VZUdmCsrY38/5166054200_220bec62b0_b_thumb%5B1%5D.jpg?imgmax=800" width="451" height="313" /&gt;&lt;/a&gt;&lt;/h4&gt;  &lt;h4&gt;A mind-bending experience&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://plaureano.blogspot.com/2010/11/redev-2010-part-1.html"&gt;Back in November 2010 of last year&lt;/a&gt;, I remember that &lt;a href="https://twitter.com/#!/gregyoung"&gt;a stranger&lt;/a&gt; walked up to me at the Green Lion Inn Bar after the Oredev conference and told me that my notion of aspects, and of object-oriented design was actually a limited version of some of the message passing capabilities of some old language named &lt;a href="http://en.wikipedia.org/wiki/Smalltalk"&gt;Smalltalk&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;He asked me to imagine for a moment that everything in OOD is a message. In original OO terminology, he said, there were methods, and messages. Whenever you call a method (in today’s terminology), what you are implicitly doing is sending a message to an object telling it to execute the code associated with that message (the method). &lt;/p&gt;  &lt;p&gt;For me, the concept of methods executing as a result of implicitly sent messages seemed fairly straightforward, but the discussion took an interesting turn.&lt;/p&gt;  &lt;p&gt;He said, “Imagine that these messages can be sent from anywhere. They can be running within the same process, running on your machine, or they can even be coming from a machine that is located halfway across the world.”&lt;/p&gt;  &lt;p&gt;The concept of Remote Procedure Calls wasn’t anything new—but the next thing he said piqued my interest.&lt;/p&gt;  &lt;p&gt;“If every method is merely a message to be sent, then any method call can be remoted [if you rewrite it with IL].”&lt;/p&gt;  &lt;p&gt;In effect, what Greg was proposing was to create a messaging system that was so granular that one could transparently take any method call on any given machine and have it execute on another machine or process without modifying the original source code. In theory, one could use such a system to split a single process so that it runs parallel on multiple machines, all without modifying the original source code.&lt;/p&gt;  &lt;p&gt;In other words, he was proposing automatic parallelization of any application using AOP, and IL rewriting.&lt;/p&gt;  &lt;p&gt;Needless to say, my jaw hit the floor, and I was left speechless.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3064656714818020077?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3064656714818020077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/cqrs-and-aop-expert-walk-into-oredev.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3064656714818020077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3064656714818020077'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/cqrs-and-aop-expert-walk-into-oredev.html' title='A CQRS and an AOP expert walk into an Oredev bar…'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/__BgjkW_AfhY/TbQJaUAqvbI/AAAAAAAAANk/VZUdmCsrY38/s72-c/5166054200_220bec62b0_b_thumb%5B1%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1673201780192952882</id><published>2011-04-24T03:29:00.001-07:00</published><updated>2011-04-24T03:29:13.851-07:00</updated><title type='text'>NDC Talk Preview: “Ten Simple Rules for Rewriting IL on the Common Language Runtime”</title><content type='html'>&lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Introduction&lt;/h4&gt;  &lt;p&gt;One of the things that frustrated me when I first started learning how to write (and rewrite) IL back in the early 2000’s was the fact that there were very few practical examples on how to do anything useful with IL. In fact, the only reliable learning tools that were available around at the time was &lt;em&gt;PEVerify.exe&lt;/em&gt;, and IL disassembler. In the six to seven years since I first started writing/rewriting IL, I often asked myself what it would take to write a useful IL tutorial that would be easy enough for someone with a minimal C# background to learn, and yet be informative enough that it would be useful to someone who has written an AOP framework of their own.&lt;/p&gt;  &lt;h4&gt;Fast forward to 2011&lt;/h4&gt;  &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/__BgjkW_AfhY/TbP7ddnbAsI/AAAAAAAAANY/N2fEm9WxOBA/s1600-h/frustrated%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="frustrated" border="0" alt="frustrated" src="http://lh5.ggpht.com/__BgjkW_AfhY/TbP7eJlZKGI/AAAAAAAAANc/221X9vuJTOA/frustrated_thumb%5B1%5D.png?imgmax=800" width="282" height="318" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Over the years, I have learned some really hard lessons about IL, and now that &lt;a href="http://plaureano.blogspot.com/2011/04/speaking-about-ten-simple-rules-for.html"&gt;I’ll be speaking at NDC 2011&lt;/a&gt;, it will be the first time that I will get to share what I have learned with the .NET community. Make no mistake—IL writing can be a &lt;a href="http://ayende.com/Blog/archive/2007/05/30/IL-Weaving--Mystery-wrapped-in-an-Enigma-containing-Frustration.aspx"&gt;“mystery wrapped in frustration containing an enigma”&lt;/a&gt;, but the good news is that I have been through many of those pitfalls, and now I can help other developers understand what’s going on when those errors occur, and I can even show you how to fix those errors.&lt;/p&gt;  &lt;h4&gt;Ten Lessons Learned&lt;/h4&gt;  &lt;p&gt;In fact, there are ten basic principles that you can follow that will make it easier for you to understand and work with IL writing/rewriting. These principles are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Rule #1:&lt;/strong&gt; If you don’t understand IL, then learn from the C# compiler&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #2:&lt;/strong&gt; Always keep the stack in a balanced state; One push = one pop&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #3:&lt;/strong&gt; Don’t forget to explicitly box/unbox your types&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #4:&lt;/strong&gt; &lt;em&gt;PEVerify.exe &lt;/em&gt;can be your best friend and worst enemy at the same time&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #5:&lt;/strong&gt; Use &lt;em&gt;Console.WriteLine()&lt;/em&gt; to triangulate errors in your IL at runtime; Use it well, and use it often&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #6:&lt;/strong&gt; GOTO statements in IL are a Good Thing™&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #7:&lt;/strong&gt; Emit as few IL instructions as possible&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #8:&lt;/strong&gt; Almost anything can be modified, including sealed classes and final methods&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #9:&lt;/strong&gt; You can replace any given method call as long as you replace it with a method that leaves the stack in the same state&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rule #10:&lt;/strong&gt; IL can be learned like any other programming language; practice makes perfect.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Many of these lessons learned are fairly straightforward, while some principles will require a bit more explanation during the talk. No matter what your level of experience in IL might be, I guarantee that this is one informative session that you won’t want to miss. Stay tuned, and I’ll see you all at NDC 2011!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1673201780192952882?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1673201780192952882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/ndc-talk-preview-ten-simple-rules-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1673201780192952882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1673201780192952882'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/ndc-talk-preview-ten-simple-rules-for.html' title='NDC Talk Preview: “Ten Simple Rules for Rewriting IL on the Common Language Runtime”'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/__BgjkW_AfhY/TbP7eJlZKGI/AAAAAAAAANc/221X9vuJTOA/s72-c/frustrated_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3533155403840848514</id><published>2011-04-22T19:45:00.001-07:00</published><updated>2011-04-22T19:45:56.644-07:00</updated><title type='text'>I’m joining Readify in Sydney, Australia!</title><content type='html'>&lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/__BgjkW_AfhY/TbI9XEtOsEI/AAAAAAAAANI/5SF9nyL-mYk/s1600-h/readify%5B2%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="readify" border="0" alt="readify" src="http://lh4.ggpht.com/__BgjkW_AfhY/TbI9XoTrsCI/AAAAAAAAANM/dT6_TcXPCqw/readify_thumb.png?imgmax=800" width="237" height="187" /&gt;&lt;/a&gt;&lt;/p&gt;      &lt;h4&gt;Way more than the average job&lt;/h4&gt;  &lt;p&gt;After a year of working for an investment bank in Hong Kong, I realized that I needed a job more meaningful than just churning out number-crunching apps for people that I would never meet or rarely ever see. Opportunity, as the saying goes, rarely ever knocks twice at a person’s door, and when &lt;a href="http://readify.net"&gt;Readify&lt;/a&gt; said that they would let me work for them after I turned them down last year to go to Hong Kong, I knew that this opportunity would never come again, and I decided to take it. It’s not every day that one gets a chance to work with some of the best developers in the .NET community, and I am humbled by the fact that I will get the chance to work with them.&lt;/p&gt;  &lt;h4&gt;Hong Kong, in Retrospect&lt;/h4&gt;  &lt;p&gt;In hindsight, living in Hong Kong has been a very comfortable experience. The city is relatively small, it has an excellent public transportation system, and you can practically get anything you want within a few keystrokes on your keyboard, a call from your mobile phone, or just by going to Mongkok to shop for the latest gadgets. For me, the problem wasn’t living in the city per se—it was the idea of having to indefinitely work on the same business apps within the same business domain for years upon years on end. Working in investment banking IT has certainly been a lucrative venture for me, but I wanted a role that would let me go out and help other clients and developers be more effective at what they do. At the same time, I wanted to work within the confines of a relatively smaller and close-knit company that gave their people more control over how they work rather than having them go through so many processes because of legal restrictions or mandated institutional regulations. &lt;/p&gt;  &lt;h4&gt;To Sydney, and Beyond&lt;/h4&gt;  &lt;p align="left"&gt;&lt;a href="http://lh3.ggpht.com/__BgjkW_AfhY/TbI9YX3PYJI/AAAAAAAAANQ/SZ7cS9KF1oc/s1600-h/3563650121_b659b9de96%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="3563650121_b659b9de96" border="0" alt="3563650121_b659b9de96" src="http://lh5.ggpht.com/__BgjkW_AfhY/TbI9Yzrv-vI/AAAAAAAAANU/v6ZM83BBARw/3563650121_b659b9de96_thumb%5B2%5D.jpg?imgmax=800" width="437" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Shortly after &lt;a href="http://plaureano.blogspot.com/2011/04/speaking-about-ten-simple-rules-for.html"&gt;my upcoming talk&lt;/a&gt; at &lt;a href="http://ndc2011.no/"&gt;NDC 2011&lt;/a&gt;, I’ll be packing all my things and I’ll be moving to Sydney, Australia to work with the folks at Readify. There’s no telling what the future holds for me, but if this job opportunity is any indication, then the future looks bright indeed.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3533155403840848514?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3533155403840848514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/im-joining-readify-in-sydney-australia.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3533155403840848514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3533155403840848514'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/im-joining-readify-in-sydney-australia.html' title='I’m joining Readify in Sydney, Australia!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/__BgjkW_AfhY/TbI9XoTrsCI/AAAAAAAAANM/dT6_TcXPCqw/s72-c/readify_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-2104076519833600661</id><published>2011-04-22T01:21:00.001-07:00</published><updated>2011-04-22T01:21:08.552-07:00</updated><title type='text'>Speaking about “Ten Simple Rules for Rewriting IL on the Common Language Runtime” at NDC 2011</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/__BgjkW_AfhY/TbE6cFKiibI/AAAAAAAAANA/ZIGmVCl6Nuc/s1600-h/Red-Pill-vs.-Blue-Pill%5B5%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Red-Pill-vs.-Blue-Pill" border="0" alt="Red-Pill-vs.-Blue-Pill" src="http://lh6.ggpht.com/__BgjkW_AfhY/TbE6c2A1H-I/AAAAAAAAANE/Rl6CrJBgqAE/Red-Pill-vs.-Blue-Pill_thumb%5B2%5D.jpg?imgmax=800" width="440" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Red or Blue&lt;/h4&gt;  &lt;p&gt;Have you ever wondered what happens under the hood of an AOP framework? Have you ever tried writing IL, only to get hit by an unintelligible wall of &lt;em&gt;PEVerify.exe&lt;/em&gt; errors?&lt;/p&gt;  &lt;p&gt;Learning how to (re)write IL can be hard, but in this session, I will show you some techniques for rewriting almost any .NET assembly with the least amount of effort and the most minimum amount of frustration possible. The art of rewriting IL will give you the ability to change programs as if you (the developer) are the compiler itself. With IL rewriting, you can add, remove, replace, unseal, and redirect method calls from any type. You can change almost any method you can possibly imagine, including methods in third party libraries that don’t have any source code publicly available. The possibilities are endless, and there’s a whole other hidden world that goes on when you compile your code into IL using your favorite .NET language, and this talk will show you just how different things are once take the red pill. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://ndc2011.no/agenda.aspx?cat=1071&amp;amp;id=-1&amp;amp;day=3728"&gt;Join me&lt;/a&gt; at NDC 2011 in Oslo at 11:40AM-12:40PM on Track 5, and I’ll show you just how deep that rabbit hole really goes.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-2104076519833600661?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/2104076519833600661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2011/04/speaking-about-ten-simple-rules-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2104076519833600661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2104076519833600661'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2011/04/speaking-about-ten-simple-rules-for.html' title='Speaking about “Ten Simple Rules for Rewriting IL on the Common Language Runtime” at NDC 2011'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/__BgjkW_AfhY/TbE6c2A1H-I/AAAAAAAAANE/Rl6CrJBgqAE/s72-c/Red-Pill-vs.-Blue-Pill_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-6058630161417478637</id><published>2010-11-15T05:54:00.001-08:00</published><updated>2010-11-15T05:54:22.144-08:00</updated><title type='text'>Øredev 2010, Part 1</title><content type='html'>&lt;a title="The Oredev poster by philip.laureano, on Flickr" href="http://www.flickr.com/photos/philiplaureano/5166055190/"&gt;&lt;img alt="The Oredev poster" src="http://farm2.static.flickr.com/1312/5166055190_60eb65c352.jpg" width="436" height="345" /&gt;&lt;/a&gt;   &lt;h4&gt;Background&lt;/h4&gt;  &lt;p&gt;Aside from becoming a great programmer, one of my lifelong dreams has always been to visit Sweden and be able to see everything that its cities have to offer. That dream finally came true last week when my employers gave me the whole week off so that I can attend the Øredev conference in Malmo, Sweden.&lt;/p&gt;  &lt;p&gt;There were so many great things that went on during that conference, and if I had to summarize it in a single word, I would call it “amazing”, and if you’re looking for a more detailed summary, here we go:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Day Zero - Old world architecture, fine dining, and bloody gooses&lt;/h4&gt; &lt;a title="Oredev 2010 Speakers Dinner - Malmo City Hall by philip.laureano, on Flickr" href="http://www.flickr.com/photos/philiplaureano/5162926883/"&gt;&lt;img alt="Oredev 2010 Speakers Dinner - Malmo City Hall" src="http://farm2.static.flickr.com/1206/5162926883_824e2e706d.jpg" width="428" height="86" /&gt;&lt;/a&gt;   &lt;p&gt;After a quick round of introductions at &lt;a href="http://twitter.com/noopman"&gt;Magnus Mårtensson's place&lt;/a&gt;, everyone walked over to the Malmo City Hall for the Speaker’s dinner. This place was huge, and according to some historians, it was the place where the Swedes celebrated victory over the Danish invaders that were trying to reconquer the southern region of Skane (the area now known as Malmo) back in the 1700s. It was the first time that I’ve ever seen such a place, and suffice to say, I was impressed.&lt;/p&gt;  &lt;p&gt;The building interior was ornate with paintings of its former Danish princes and rulers, and the far end of the Council Room had images of its Swedish victors. The deputy mayor of the City of Malmo stood in front of all the attendees and welcomed us to the city. I watched as everyone lifted their champagne glasses to toast the event, and at first, I thought that we were just going to stand around in the Council Room and have a cocktail party. Ten minutes later, they escorted us into a huge dining hall, and the surroundings were like something out of an old world fairy tale.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh5.ggpht.com/__BgjkW_AfhY/TOE7dy0oF7I/AAAAAAAAALk/tnlvDcxtnl8/s1600-h/IMG_0141%5B7%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_0141" border="0" alt="IMG_0141" src="http://lh4.ggpht.com/__BgjkW_AfhY/TOE7enrkZ_I/AAAAAAAAALo/HBR3ZfebNZo/IMG_0141_thumb%5B4%5D.jpg?imgmax=800" width="446" height="292" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After everyone found their seats among the various open tables, the waiters started serving us various types of white and red wines. Everything seemed normal up to that point, until the waiters served this one mysterious bowl of soup:&lt;/p&gt; &lt;a title="Goose Blood Soup by philip.laureano, on Flickr" href="http://www.flickr.com/photos/philiplaureano/5163598946/"&gt;&lt;img alt="Goose Blood Soup" src="http://farm5.static.flickr.com/4087/5163598946_198088acde.jpg" width="437" height="345" /&gt;&lt;/a&gt;  &lt;p&gt;At first, I thought it was some bowl of chocolate-flavored syrup. After all, as I naively told myself, the Swedes must be known for their chocolate. As it turns out, it was the Swiss (not the Swedes) that were known for their chocolate, and that “special” soup was actually a bowl that was chalk full of goose blood. When I asked the waiter what was in the bowl, he just gave me a weird look and said, “they didn’t tell you what was in the bowl?”&lt;/p&gt;  &lt;p&gt;I just shook my head and waved the bowl away, and if weren’t for my vegetarian tendencies, I probably would have become an avian vampire. After picking and eating the meatless option (which was the lobster soup), I went around the room and took a few pictures of some of the notable speakers that were at the conference:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/__BgjkW_AfhY/TOE7gFxfnhI/AAAAAAAAALs/-B9uFcdrnIU/s1600-h/IMG_0144%5B4%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_0144" border="0" alt="IMG_0144" src="http://lh5.ggpht.com/__BgjkW_AfhY/TOE7gyvwZ6I/AAAAAAAAALw/Dzm-JCLTkmI/IMG_0144_thumb%5B1%5D.jpg?imgmax=800" width="441" height="306" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;h6&gt;Center: Jeremy Miller, aka “The Shade Tree Developer”&lt;/h6&gt;  &lt;p&gt;What surprised me was that many of the developers that I had been reading about for many years were sitting right there in front of me in that dining hall. They were no longer just some prestigious names on a random blog post on a programmer site. They were there, &lt;em&gt;en vivo&lt;/em&gt;, and it was nice to finally be able to match a face to each one of their names.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__BgjkW_AfhY/TOE7hR5_pCI/AAAAAAAAAL0/eizqLqzAq_A/s1600-h/IMG_0162%5B3%5D.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_0162" border="0" alt="IMG_0162" src="http://lh6.ggpht.com/__BgjkW_AfhY/TOE7inxm4YI/AAAAAAAAAL4/tWCTQsiqxVo/IMG_0162_thumb.jpg?imgmax=800" width="244" height="164" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h6&gt;Center: Roy Osherove, author of “The Art of Unit Testing in .NET”, and Hadi Hariri, Tech Evangelist at Jetbrains&lt;/h6&gt;  &lt;p&gt;For the most part, the rest of the dinner was filled with toasts and speeches from the Øredev organizers. Overall, I’d say that the food was excellent, and as introductory dinners go, it was filled with lots of people getting to know each other over bleeding gooses. For me, it was remarkable for its attendees, but relatively unremarkable for the dinner chatter. &lt;/p&gt;  &lt;p&gt;Things didn’t get interesting until we all left Malmo City Hall and went to the Green Lion Inn. After spending about an hour talking to Hadi (Hariri) about emergent refactoring techniques, he said that he had to get some sleep because he had to be at the Jetbrains booth very early by the next morning, so I said goodbye to him, and he left.&lt;/p&gt;  &lt;p&gt;I was tired too, and I figured that I should go back to my room and get some rest. My internal body clock was seven hours ahead of my physical location, and I was headed for the door until some stranger approached me and told me that he wanted to talk to me about AOP. The two-hour conversation about AOP that soon followed seriously changed the way I saw AOP, and that stranger was no ordinary stranger.&lt;/p&gt;  &lt;p&gt;It was Greg Young, and he blew me away with what he had to say.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;…to be continued&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-6058630161417478637?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/6058630161417478637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2010/11/redev-2010-part-1.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6058630161417478637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6058630161417478637'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2010/11/redev-2010-part-1.html' title='Øredev 2010, Part 1'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1312/5166055190_60eb65c352_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-5301977795878761357</id><published>2010-03-07T03:14:00.000-08:00</published><updated>2010-03-07T03:14:57.136-08:00</updated><title type='text'>Announcement: LinFu is now on Github!</title><content type='html'>LinFu has been my obsession for the better part of six years, and despite all its features, almost every patch, fix, and feature request has been handled by one and only one person--&lt;a href="http://plaureano.blogspot.com"&gt;me&lt;/a&gt;. After three years, the codebase itself has become quite mature, and I realize that there will be some point where I have to completely open this project up to the rest of the community so that it can grow and this is just the first step.&lt;br /&gt;&lt;br /&gt;Today, I'm happy to announce that all of LinFu version 2.0 &lt;a href="http://github.com/philiplaureano/LinFu"&gt;has been moved to Github&lt;/a&gt; (under the same LGPL license), and you can fork it as much as you want. I will still actively maintain it (just as I maintained it on google code), but the difference is that anyone here can make changes to the project and I will be more than happy to accept pull requests. &lt;br /&gt;&lt;br /&gt;No man is an island, and now it's time to swim in the sea of possibilities.&lt;br /&gt;&lt;br /&gt;Happy forking, and let me know if you come up with anything interesting :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-5301977795878761357?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/5301977795878761357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2010/03/announcement-linfu-is-now-on-github.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5301977795878761357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5301977795878761357'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2010/03/announcement-linfu-is-now-on-github.html' title='Announcement: LinFu is now on Github!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-2206168811399654381</id><published>2009-12-24T18:02:00.000-08:00</published><updated>2009-12-24T20:52:44.043-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiro ioc codeproject dynamic'/><title type='text'>Introducing Hiro.Functors, and Making Hiro a Dynamic Container</title><content type='html'>One of the more salient criticisms that I've often heard about Hiro is the fact that for the most part, the containers that Hiro creates are static and cannot be modified once they have already been compiled and instantiated. There might even be cases where you might have to have a Hiro-compiled container return an existing service instance, and that service instance (in turn) might not be available when the container is first compiled. For example, let's assume that you have an existing service instance of class type Foo that implements the IFoo interface:&lt;br /&gt;&lt;br /&gt;public interface IFoo&lt;br /&gt;{&lt;br /&gt;    // ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Foo : IFoo&lt;br /&gt;{&lt;br /&gt;    // ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Let's also assume that Foo is some sort of long running service that must be returned every time you ask for an IFoo instance from a Hiro-compiled container. In previous revisions of Hiro, you probably could have registered the IFoo service as a singleton using the following code:&lt;br /&gt;&lt;br /&gt;var map = new DependencyMap();&lt;br /&gt;map.AddSingletonService&lt;IFoo, Foo&gt;();&lt;br /&gt;&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;// ..Use the container code here&lt;br /&gt;&lt;br /&gt;The problem with the previous code above is that you can't use it if the Foo instance has already created before the container instance has been compiled. Since the hypothetical Foo service is a long-running service that already exists before each container is compiled, there doesn't seem to be any way to make a DependencyMap return an existing object instance--that is, until now. This is where Hiro.Functors comes to the rescue:&lt;br /&gt;&lt;br /&gt;// For the sake of simplicity, let's assume that Foo has already been instantiated..&lt;br /&gt;var existingFooInstance = new Foo();&lt;br /&gt;&lt;br /&gt;// Define the factory functor&lt;br /&gt;Func&amp;lt;IMicroContainer, object&amp;gt; makeFoo =&amp;gt;existingFooInstance;&lt;br /&gt;&lt;br /&gt;var map = new DependencyMap();&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;map.AddService(typeof(IFoo), makeFoo);&lt;/span&gt;&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;// Get the foo service; The makeFoo functor will be called here&lt;br /&gt;var actualFoo = container.GetInstance&lt;IFoo&gt;();&lt;br /&gt;&lt;br /&gt;// This will evaluate to true&lt;br /&gt;Assert.AreSame(existingFooInstance, actualFoo);&lt;br /&gt;&lt;br /&gt;As you can see from the code above, the Hiro.Functors library extends Hiro so that you can use C#'s native lambda syntax to add your own custom factory methods to any Hiro-compiled container. A single call to the additional DependencyMap.AddService(yourServiceType, yourFunctor) is all you need to convert Hiro from a static container to a dynamic container without sacrificing speed for flexibility. It's just that simple.&lt;br /&gt;&lt;br /&gt;I prefer to call Hiro the "blue collar" IOC container framework, and Hiro.Functors is just another step in helping you (the end-user developer) get the job done with as little drama as possible in the fewest amount of steps possible. While there's definitely nothing revolutionary about this tiny release, I think there's plenty to be said about having an IOC container that gets in and does the job using the flattest learning curve possible, and that's exactly what Hiro offers. &lt;br /&gt;&lt;br /&gt;While I can't promise my readers that I'll change the world with revolutionary tools, what I will promise them is that my tools will be the simplest tools that they can possibly use so that they'll be able to meet their deadlines on time and make it home early for holidays like today. Hiro is one such tool, and if you ever run into any problems with it, I'm only a patch and an email away. Happy holidays, everyone!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(Note: You can get Hiro.Functors &lt;a href="http://code.google.com/p/hiro-contrib/source/checkout"&gt;here&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-2206168811399654381?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/2206168811399654381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/12/introducing-hirofunctors-and-making.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2206168811399654381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2206168811399654381'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/12/introducing-hirofunctors-and-making.html' title='Introducing Hiro.Functors, and Making Hiro a Dynamic Container'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-5309986570257573474</id><published>2009-09-09T16:01:00.000-07:00</published><updated>2009-09-09T16:33:58.084-07:00</updated><title type='text'>Creating Per-Session Services with Hiro</title><content type='html'>Over the past week, I've had a few people ask me how they can use Hiro to create services that are instantiated once per web session. Ideally, Hiro should be able to do something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="csharp"&gt;&lt;br /&gt;&lt;br /&gt;// Instantiate the IFoo service&lt;br /&gt;var context = HttpContext.Current;&lt;br /&gt;&lt;br /&gt;if (context.Session["SomeFooKey"] == null)&lt;br /&gt;  context.Session["SomeFookey"] = container.GetInstance&amp;lt;IFoo&amp;gt;();&lt;br /&gt;&lt;br /&gt;return (IFoo)context.Session["SomeFooKey"];&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The code itself is pretty simple, but the problem is that this can get quite cumbersome if you have more than a few services that need to be stored in the Session object. There has to be some way to do this with Hiro using a single method call, and indeed, Hiro makes creating per-session services just as equally effortless:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="csharp"&gt;&lt;br /&gt;// Register the Foo service into the DependencyMap&lt;br /&gt;var map = new DependencyMap();&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;map.AddPerSessionService(typeof(IFoo), typeof(Foo));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Compile the container&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;var foo = container.GetInstance&amp;lt;IFoo&amp;gt;();&lt;br /&gt;&lt;br /&gt;// ...use the IFoo per-session service here (just like any other service)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see from the example above, Hiro abstracted away the details of having to deal with caching your services into a Session object. In fact, all you have to do to add per-session services to your dependency maps is to use the &lt;span style="font-style: italic;"&gt;AddPerSessionService&lt;/span&gt; extension method, compile your container and use it like any other Hiro-compiled container. It's just that simple.&lt;br /&gt;&lt;br /&gt;NOTE: You can download the Hiro.Web extensions (including the per-session service support extension method) &lt;a href="http://code.google.com/p/hiro-contrib/source/checkout"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-5309986570257573474?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/5309986570257573474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/09/creating-per-session-services-with-hiro.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5309986570257573474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5309986570257573474'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/09/creating-per-session-services-with-hiro.html' title='Creating Per-Session Services with Hiro'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3214101499232928563</id><published>2009-07-27T15:57:00.000-07:00</published><updated>2009-07-28T21:07:06.758-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiro ioc codeproject dotnet'/><title type='text'>Introducing Hiro, the World's Fastest IOC Container, Part III: The Container Itself</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Introduction&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this final installment of the Hiro series, I'll show you just how ridiculously simple it is to use Hiro in your own applications without sacrificing speed for simplicity. I'll also show you how you can use Hiro's registration conventions so that you will never have to worry about managing any external configuration files or declare any external attributes on your types just so you can get your types registered into a service container.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Simply Fast, and Simply Simple&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As I mentioned in &lt;a href="http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc_15.html"&gt;my previous posts&lt;/a&gt;, Hiro lacks many of the "fat" features that you would normally associate with other IOC containers (including LinFu). At first, that might seem like a disadvantage for potential Hiro users, but it also implies that you won't have to waste any time trying to understand any IOC container features that you probably will never use in most of your applications. Instead, Hiro focuses on doing three things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Determine the list of available services from any given assembly.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Registering those services into a container&lt;/li&gt;&lt;li&gt;Ensuring that the container can create the services that you registered.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Unlike other IOC containers, Hiro doesn't need you to use fluent interfaces or attributes to register your types into a container. You don't even need lambda functions or an external XML configuration file to get your services up and running with Hiro. Instead, Hiro uses &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration"&gt;Convention over Configuration&lt;/a&gt; semantics that let you register your services with only a few lines of code. Here's an example:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// Use the loader to scan the target assembly&lt;br /&gt;// for services&lt;br /&gt;var loader = new DependencyMapLoader();&lt;br /&gt;&lt;br /&gt;// The loader will handle all the details of loading&lt;br /&gt;// the services into the container for you&lt;br /&gt;DependencyMap map = loader.LoadFromBaseDirectory("SampleDomain.dll");&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;// (Do something useful with the container here)&lt;br /&gt;var greeter = container.GetInstance&amp;lt;IGreeter&amp;gt;();&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"Convention over...what?"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At first glance, it's hard to believe that Hiro can load all the services from a given assembly (or a set of assemblies) using only the code that was given in the previous example. After all, any given service can have nearly an infinite amount of constructor and property injection dependencies, and given the sheer complexity of this task, there must be a set of rules that Hiro follows that somehow makes the registration happen "automagically". At the same time, there might be some end-user developers out there that might want to have strict control over the actual services that will be registered into the compiled container. In other words, how does Hiro know exactly what to register and still be able let users control what gets registered into a compiled container?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Few Rules Go A Long Way&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now the reason why Hiro can do so much in so few lines of code is because that it implements a few conventions that typical IOC container users would follow when registering their own types. As long as users follow those conventions, they will never have to worry about manually registering any of their service types with Hiro. For example, let's assume that you had this particular service type declared in a single assembly:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;  &lt;br /&gt;  public interface IGreeter&lt;br /&gt;  {&lt;br /&gt;      void Greet(string name);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's also assume that you have three concrete classes that implement the same IGreeter interface:&lt;br /&gt;&lt;pre lang="cs"&gt;  &lt;br /&gt;  public class GermanGreeter : IGreeter&lt;br /&gt;  {&lt;br /&gt;      public void Greet(string name)&lt;br /&gt;      {&lt;br /&gt;          Console.WriteLine("German: Hallo, {0}!!");&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public class FrenchGreeter : IGreeter&lt;br /&gt;  {&lt;br /&gt;      public void Greet(string name)&lt;br /&gt;      {&lt;br /&gt;          Console.WriteLine("French: Bonjour, {0}!", name);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public class Greeter : IGreeter&lt;br /&gt;  {&lt;br /&gt;      public void Greet(string name)&lt;br /&gt;      {&lt;br /&gt;          Console.WriteLine("English: Hello, {0}!", name);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"Just give me the default service, please!"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Based on the examples above, it probably didn't take you very long to infer that the Greeter class is the default implementation for the IGreeter interface. Furthermore, it's probably safe to assume that a default implementation exists if you have an interface named IYourService and if you already have a concrete class named YourService that implements that particular service type. Hiro follows the same convention, so calling container.GetInstance on an IGreeter type will yield a Greeter instance:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;  &lt;br /&gt;&lt;br /&gt;// Load the sample assembly&lt;br /&gt;var loader = new DependencyMapLoader();&lt;br /&gt;DependencyMap map = loader.LoadFromBaseDirectory("SampleDomain.dll");&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;// Get the default implementation&lt;br /&gt;var greeter = container.GetInstance&amp;lt;IGreeter&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Determine the actual type that implements the IGreeter interface&lt;br /&gt;var greeterType = greeter.GetType();&lt;br /&gt;&lt;br /&gt;// This expression will return true&lt;br /&gt;Console.WriteLine(greeterType == typeof(Greeter));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the example above is fairly self-explanatory. The DependencyMapLoader class will automatically determine that the Greeter type is the default implementation for the IGreeter interface and register it into the DependencyMap. Of course, this approach assumes that you have a class with a type name that matches the service type name; however, there might be cases where you have multiple classes that implement the same interface but don't follow this naming convention. For example, if I have the FrenchGreeter and a GermanGreeter class but don't have a default Greeter class, how does Hiro determine which implementation should be used as the default implementation type?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When All Else Fails, Use the Alphabet&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The answer is that by default, Hiro will pick the first implementation type from a list of service implementations that have been sorted alphabetically by type name. In this case, Hiro will choose the FrenchGreeter as the default IGreeter implementation since the FrenchGreeter class name alphabetically appears before the GermanGreeter class name:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;// Get the default implementation&lt;br /&gt;var greeter = container.GetInstance&amp;lt;IGreeter&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Determine the actual type that implements the IGreeter interface&lt;br /&gt;var greeterType = greeter.GetType();&lt;br /&gt;&lt;br /&gt;// This expression will return true since&lt;br /&gt;// the FrenchGreeter type appears before the GermanGreeter type&lt;br /&gt;Console.WriteLine(greeterType == typeof(FrenchGreeter));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;While this approach might be useful for determining (and thus accessing) a default service implementation, there has to be a way to access the other concrete IGreeter implementations that reside in the compiled container. As it turns out, Hiro makes this process just as equally effortless:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// Get the French and German greeters&lt;br /&gt;var frenchGreeter = container.GetInstance&amp;lt;IGreeter&amp;gt;("FrenchGreeter");&lt;br /&gt;var germanGreeter = container.GetInstance&amp;lt;IGreeter&amp;gt;("GermanGreeter");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;By default, Hiro registers each service implementation using the class name of each concrete service type. In order to access a particular service implementation, all you need to do is pass the name of the implementing type in the container.GetInstance&amp;lt;T&amp;gt; call, and the container will instantiate the corresponding type for you.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using Constructor Injection and Property Injection&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we have an idea of how Hiro registers service types into a container, the next thing that you might be wondering about is exactly how Hiro injects dependencies into constructors and properties. For example, if I have a class named GreeterHost that takes one IGreeter dependency in its constructor, how do I tell Hiro to use that constructor instead of the default constructor? Let's take a look at the GreeterHost class:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;public class GreeterHost&lt;br /&gt;{&lt;br /&gt;  public GreeterHost ()&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;  public GreeterHost(IGreeter greeter)&lt;br /&gt;  {&lt;br /&gt;     // Do something useful here&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's also assume that I manually registered the GreeterHost class with the DependencyMap using the DependencyMap.AddService method. Here's how you get Hiro to perform constructor injection:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;&lt;br /&gt;// Manually add the GreeterHost to the dependency map&lt;br /&gt;var map = new DependencyMap();&lt;br /&gt;map.AddService&amp;lt;GreeterHost, GreeterHost&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Manually add an IGreeter service so that Hiro uses the constructor&lt;br /&gt;// with the IGreeter parameter&lt;br /&gt;map.AddService&amp;lt;IGreeter, Greeter&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Compile the container&lt;br /&gt;var container = map.CreateContainer();&lt;br /&gt;&lt;br /&gt;// Create the GreeterHost. Hiro will automatically&lt;br /&gt;// inject the IGreeter implementation into the constructor&lt;br /&gt;var greeterHost = container.GetInstance&amp;lt;GreeterHost&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see from the example above, Hiro automatically used the contents of the dependency map to determine which constructor should be used for instantiating the GreeterHost type. The only thing that I needed to do to perform constructor injection was to make sure that the IGreeter service type was available in the dependency map once the container was compiled. The compiled container, in turn, used the IGreeter dependency to call the correct GreeterHost constructor.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Singletons Galore&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NOTE: If you prefer to have your Greeter type registered as a singleton in the dependency map, however, here's how you do it:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// Manually add an IGreeter service so that Hiro uses the constructor&lt;br /&gt;// with the IGreeter parameter&lt;br /&gt;map.AddSingletonService&amp;lt;IGreeter, Greeter&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Constructor, Inject Thyself&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The best part about the constructor injection example with Hiro is the fact that it handles all the gory details of performing constructor injection for you in the most minimal lines of code possible. In this case, the only convention that you have to follow is to make sure that the dependency map contains all the necessary services for Hiro to call the appropriate constructor. What makes this even more interesting is that Hiro can perform automatic constructor injection with constructors that have any arbitrary number of constructor arguments. In other words, if the DependencyMap instance has the constructor dependency, then Hiro can handle the injection.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Property, Inject Thyself Too&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For the most part, Hiro's property injection follows some of the same conventions as constructor injection. Much like constructor injection, the only thing you need to do to use property injection with Hiro is to make sure that services required by the target property are already registered with the dependency map once the container is compiled. For example, let's assume that GreeterHost class as an IGreeterProperty named CurrentGreeter:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;public class GreeterHost&lt;br /&gt;{&lt;br /&gt;  public IGreeter CurrentGreeter&lt;br /&gt;  {&lt;br /&gt;     get;set;     &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's how you set up Hiro's dependency map to perform property injection:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// Manually add the GreeterHost to the dependency map&lt;br /&gt;var map = new DependencyMap();&lt;br /&gt;map.AddService&amp;lt;GreeterHost, GreeterHost&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Manually add an IGreeter service so that Hiro uses the constructor&lt;br /&gt;// with the IGreeter parameter&lt;br /&gt;map.AddService&amp;lt;IGreeter, Greeter&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first thing that you might notice is that the setup code for property injection and constructor injection are both identical to each other. In fact, you could even say that I just "copy &amp;amp; pasted" the example from previous examples in this article. Indeed, that was intentional, and the point here is that are only two simple things that you need to do to make Hiro automatically perform property injection on your types:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ensure that the service types that your properties require are registered with the dependency map.&lt;/li&gt;&lt;li&gt;Ensure that the properties that will be injected are not read-only properties.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;In other words, Hiro's property injection conventions follow one of the most basic dependency injection conventions of all:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;If you don't want Hiro to inject dependencies into your target property, then make sure the property is a read-only property or the property type doesn't exist in the container as a service type.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;All you need to do to disable property injection for the GreeterHost is to prevent a default IGreeter service from ever being registered into the dependency map. You can do this by either constructing the dependency map by hand, or you can attach a service filter to the DependencyMapLoader so that it avoids loading a default IGreeter service into the resulting dependency map:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;var loader = new DependencyMapLoader();&lt;br /&gt;&lt;br /&gt;// Make sure that no default service is loaded for the IGreeter interface&lt;br /&gt;loader.ServiceFilter = service=&gt;service.ServiceType != typeof(IGreeter) &amp;&amp; string.IsNullOrEmpty(service.ServiceName);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see from the example above, all you need to do to prevent the DependencyMapLoader from registering services is use a simple lambda function, and it can't get any simpler than that.&lt;br /&gt;&lt;br /&gt;Next, here's the call that will construct the GreeterHost and perform the property injection operation if you still have the required dependency inside the container: &lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;// This is the only method call you need&lt;br /&gt;// to do property injection&lt;br /&gt;var greeterHost = container.GetInstance&amp;lt;GreeterHost&amp;gt;();&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fortunately for the end-user developer, the GetInstance method that performs the constructor injection is also the same method that will perform all property injection operations. Hiro uses these simple conventions to make developers' lives easier, and if it can help at least one person out there write better code, then I consider this project to be a success.&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;You can download Hiro from &lt;a href="http://is.gd/1S4j4"&gt;here&lt;/a&gt;.&lt;br /&gt;You can also &lt;a href="http://is.gd/1S4OE"&gt;click here&lt;/a&gt; to download the Hiro example solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3214101499232928563?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3214101499232928563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/07/introducing-hiro-worlds-fastest-ioc.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3214101499232928563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3214101499232928563'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/07/introducing-hiro-worlds-fastest-ioc.html' title='Introducing Hiro, the World&apos;s Fastest IOC Container, Part III: The Container Itself'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-8141072638969660469</id><published>2009-07-16T18:47:00.000-07:00</published><updated>2009-07-16T20:33:12.149-07:00</updated><title type='text'>NDepend Review</title><content type='html'>&lt;span style="font-weight: bold;"&gt;The Quick &amp;amp; Dirty&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There have been a &lt;a href="http://www.google.com/search?q=ndepend+review&amp;amp;hl=en&amp;amp;start=20&amp;amp;sa=N"&gt;lot of good reviews&lt;/a&gt; written for NDepend, so for the sake of efficiency, I'll get straight to the point: &lt;span style="font-weight: bold;"&gt;NDepend is an amazing tool&lt;/span&gt;. It lets you graphically inspect your assemblies and it lets you pinpoint the spots in your code base that need refactoring.&lt;br /&gt;&lt;br /&gt;So would I recommend buying NDepend Professional? &lt;span style="font-weight: bold;"&gt;Yes&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Is there something that I didn't like about NDepend that I think the users should know about? &lt;span style="font-weight: bold;"&gt;Yes&lt;/span&gt;, and that's exactly what I'll talk about.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"So what's not to like about NDepend?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My only problem with NDepend is that its CQL query engine can only be accessed from the Visual NDepend application. NDepend does let you embed CQL attributes in your applications, but the problem is that I shouldn't have to force each one of my applications to have a dependency on NDepend just because I want to have some code metrics calculations in my build process. Of course, there are a few ways that I can work around that limitation, but the point is that I shouldn't have to make a workaround for something that should have been there in the first place.&lt;br /&gt;&lt;br /&gt;In other words, what NDepend sorely needs right now is a publicly-accessible CQL engine API. If NDepend is truly a tool built by developers for developers, then it should have an API that other developers can use to analyze their applications. It's not enough to throw them a rudimentary command-line tool that spits out code metrics in XML--that pretty much leaves developers to write code against the "shadow" of the CQL API rather than write against the CQL API itself, and for me, that just doesn't quite cut it.&lt;br /&gt;&lt;br /&gt;Don't get me wrong--the Visual NDepend winforms application is an awesome app--but I'd rather be able to filter through all that information using a single API call rather than have to manually sift through several windows just to find the information I need.&lt;br /&gt;&lt;br /&gt;Now the reason why I'm harping so much about the lack of a public CQL API is that &lt;a href="http://www.codelean.com/"&gt;my company&lt;/a&gt; uses NDepend Professional in its command line builds to ensure that our builds fail when the Cyclomatic Complexity score exceeds 2.5 in any of our projects. The problem is that we want our code quality inspections to be completely automated, and we can't do that unless we have access to the CQL API and can generate CQL queries at runtime. The maximum Cyclomatic Complexity score might prevent our developers from writing complicated code, but there's far more to code inspections than just looking at a single score. What we need is a way to look deeper into the quality of our code base using the hypothetical CQL API with the same ease that Visual NDepend users can browse through their code.&lt;br /&gt;&lt;br /&gt;So in the end, I still recommend NDepend Pro as definite buy, but it still lacks a few key features that would make me give Patrick Smacchia's tool the gushing review that other bloggers have given it in their respective reviews. Overall, it's definitely a great tool, but it's not without a few shortcomings.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;[Public Disclosure: Thanks to Patrick Smacchia for providing me with a free NDepend Pro license for this review.]&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-8141072638969660469?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/8141072638969660469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/07/ndepend-review.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8141072638969660469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8141072638969660469'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/07/ndepend-review.html' title='NDepend Review'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-446687795186661198</id><published>2009-04-15T16:06:00.000-07:00</published><updated>2009-04-15T17:33:33.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiro ioc codeproject'/><title type='text'>Introducing Hiro, the World's Fastest IOC Container, Part II: The Little Feature Set That Could</title><content type='html'>&lt;span style="font-weight: bold;"&gt;The Art of Lean&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that everyone knows just how fast Hiro can be, the next question you might be asking yourself is, "What features will it support?"&lt;br /&gt;&lt;br /&gt;The simplest answer that I can give is that Hiro is that it will implement as little features as possible--in fact, Hiro will implement &lt;span style="font-style: italic;"&gt;so little features&lt;/span&gt; that it might turn away your traditional "dynamic" IOC user. Here's the features that Hiro will implement:&lt;br /&gt;&lt;br /&gt;-&lt;span style="font-weight: bold;"&gt;Named/Anonymous Static Component Registration.&lt;/span&gt; This means that you'll be able to register your services using a service name, service type, and the implementing type.&lt;br /&gt;&lt;br /&gt;-&lt;span style="font-weight: bold;"&gt;Convention Over Configuration for Registration and Injection.&lt;/span&gt;. In addition to its support for programmatic registration, Hiro will be able to scan your assemblies and automatically infer:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The list of available services&lt;/li&gt;&lt;li&gt;The list of concrete types that implement those services&lt;/li&gt;&lt;li&gt;The list of properties that can be injected&lt;/li&gt;&lt;li&gt;The constructors that will be used for constructor injection&lt;/li&gt;&lt;li&gt;The services that will be injected into each parameter during a constructor injection call.&lt;/li&gt;&lt;/ol&gt;The most interesting part about this is the amount of work that will take to do this sort of registration. Take a look at this example:&lt;br /&gt;&lt;br /&gt;&lt;pre lang="cs"&gt;&lt;br /&gt;          var loader = new DependencyMapLoader();&lt;br /&gt;          var map = loader.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "Yourlibrary.dll");&lt;br /&gt;&lt;br /&gt;          IContainerCompiler compiler = new ContainerCompiler();&lt;br /&gt;          var microContainer = compiler.Compile(map);&lt;br /&gt;&lt;br /&gt;          // Do something with the container here&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Believe it or not, this is the only code that you need to use to configure the dependencies for any assembly of any given size. What makes this even more interesting is the fact that &lt;span style="font-weight: bold;"&gt;all of this is done statically at (container) compile time, not runtime&lt;/span&gt;. This means that unlike the current generation of IOC containers, Hiro will not waste any time trying to rediscover your configuration, and based on the benchmark results from my &lt;a href="http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc.html"&gt;previous post&lt;/a&gt;, the performance numbers are nothing short of being dramatically one-sided.&lt;br /&gt;&lt;br /&gt;-&lt;span style="font-weight: bold;"&gt;Transient/Singleton instances.&lt;/span&gt; Aside from performance, however, Hiro has to be able to create both Transient (that is, plain old object instances created with the New operator) and Singleton instances.&lt;br /&gt;&lt;br /&gt;-&lt;span style="font-weight: bold;"&gt;Property/Constructor Injection.&lt;/span&gt; Hiro will implement both property and constructor injection by default. What makes this even more interesting is that like everything else with Hiro, all property and constructor injection calls will all be precompiled into IL, meaning that there will be no performance issues when using Hiro.&lt;br /&gt;&lt;br /&gt;-&lt;span style="font-weight: bold;"&gt;Stateless&lt;/span&gt;. Each Hiro-compiled container instance will not have any private local data (or even shared data) that will distinguish it from another compiled container of the same type. This means that you can scale Hiro's compiled containers across multiple cores AND multiple threads without using a single semaphore, mutex, or lock statement (in C#).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"But wait, your container isn't a REAL container until you implement feature X!"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some would argue that Hiro would have to implement a minimum "baseline" feature set in order to be considered a "commercial" quality IOC container. However, my counterargument there is that it's this same "fat feature" mindset that got these IOC containers (including LinFu) into this speed problem in the first place. Secondly, if you're experienced enough about IOC to understand the significance of what Hiro does, then it's safe to assume that you're a user that falls into at least one of the following categories:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You've probably written at least one IOC container framework, or&lt;/li&gt;&lt;li&gt;You already are comfortable with an existing IOC container framework (such as Castle, Ninject, AutoFac, Unity, StructureMap, LinFu, etc) and you know enough to customize it to your needs.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Assuming that you're an IOC container author, it would be pointless for me to implement something in Hiro that you've probably rolled into your own framework, and given that you're skilled enough to write your own framework, it would be practically trivial for you to plug Hiro into your own framework and reap the performance benefits, and there's clearly no reason to reinvent the wheel here if you somehow did a better job than I did in implementing "feature X".&lt;br /&gt;&lt;br /&gt;Now, if you think you're a user that falls into the second category, there's a good chance that you've pretty much decided to stick to the favorite framework of your choice, and like the other IOC container authors, there's really nothing that I can do for you unless you decide to plug in Hiro into your favorite container.&lt;br /&gt;&lt;br /&gt;So between these two types of users, who do you think Hiro is written for?&lt;br /&gt;&lt;br /&gt;Here's my answer: &lt;span style="font-weight: bold;"&gt;Neither one of them&lt;/span&gt;. Hiro is written for the average developer who wants to get started with an IOC container and doesn't have time to "geek out" over the latest and greatest features of an IOC container framework. Given that there are probably far better IOC container developers than myself, I've pretty much decided to skip the "my container is better than your container" religious wars and focus on what really matters: the end users.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Pareto Pleasure Principle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hiro doesn't need to implement 80% of the expected features of an IOC container in order to be useful--instead, it only has to implement the other 20% of the overall features that (in my opinion) people will actually use. In the end, if I can help those people get their jobs done in the simplest possible way without forcing them to wade through the "awesomeness" of my framework, then I would call Hiro a success, and at the end of the day, that's really all that matters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-446687795186661198?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/446687795186661198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc_15.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/446687795186661198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/446687795186661198'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc_15.html' title='Introducing Hiro, the World&apos;s Fastest IOC Container, Part II: The Little Feature Set That Could'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1347962814343708249</id><published>2009-04-07T16:42:00.000-07:00</published><updated>2009-04-14T16:32:14.289-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiro linfu ioc dotnet codeproject'/><title type='text'>Introducing Hiro, the World's Fastest IOC Container, Part I: Design Diary</title><content type='html'>Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Have you ever had one of those moments where someone told you that your work sucked, and it inspired you to create something better? About a month ago,&lt;a href="http://www.codeproject.com/script/Forums/View.aspx?fid=1532288&amp;msg=2962114"&gt;Alex Simkin sent me a message&lt;/a&gt; on the CodeProject forums for one of my articles saying that &lt;span style="font-weight:bold;"&gt;LinFu ranked second to last in performance&lt;/span&gt; among all the other containers, and that he was willing to show me the benchmark code that produced those numbers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Eating the Humble Pie&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, Alex was correct. Despite all of its features, LinFu landed a spot near the bottom of the pack, and needless to say, there had to be a better way to design a container so that it wouldn't have these bottlenecks. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;"But...but...my container is dynamic and it's flexible!"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As an IOC container author myself, I've probably given that same excuse a dozen times over whenever someone complained that my framework was too slow. I never realized that the flexibility that I so touted in all my IOC articles was the same cause for all my performance headaches. Indeed, there had to be some way to improve these numbers, and at first, I thought adding more dynamic IL generation would solve the problem. After all, Lightweight Code Generation with DynamicMethod seems to be the trend nowadays among the other frameworks like Ninject, and that makes their code run faster, right?&lt;br /&gt;&lt;br /&gt;Once again, I was wrong. DynamicMethods didn't make much of a performance impact because Ninject (which reportedly uses a lot of LCG its code) was actually the slowest among all of the IOC containers tested in the benchmark (Sorry Nate). Of course, this doesn't mean that the DynamicMethod approach is the cause of the slowdown; what it does suggest, however, is that piling more and more reflection onto the speed problem is not the solution. In addition, there were other frameworks in that benchmark (such as Funq) that didn't use any reflection at all, and yet, they still were taking significant performance hits on that benchmark. In fact, even the fastest among all the other containers--StructureMap--&lt;span style="font-weight:bold;"&gt;was still running forty-four times slower&lt;/span&gt; than the Plain/No Dependency Injection use case!&lt;br /&gt;&lt;br /&gt;So the principle question is this: &lt;span style="font-style:italic;"&gt;"Where is this bottleneck coming from, and how do I eliminate it?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;The Real Problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As it turns out, the answer was staring me in the face all along: &lt;span style="font-style:italic;"&gt;"It's the configuration, stupid"&lt;/span&gt;, I thought to myself. The problem is that every major IOC container at the time of this post (such as Ninject, StructureMap, Unity, AutoFac, Castle, LinFu, etc) essentially has to trawl through each one of its dependencies just to instantiate a single service instance on every call, and practically no amount of optimization will ever compensate for the fact that they still have to "rediscover" any given part of an application's configuration in order to instantiate that one service instance. Needless to say, this rediscovery process wastes a huge amount of resources because these containers are actually "rediscovering" a configuration that (for all practical purposes) will rarely change between two successive method calls. &lt;br /&gt;&lt;br /&gt;In layman's terms, this is akin to stopping and asking for directions &lt;span style="font-weight:bold;"&gt;at every intersection&lt;/span&gt; every time you want to leave your home to go to some other destination. There has to be some way to see the "whole map" and plan the trip ahead of time without having to stop for directions at every intersection. If you could plan all the possible routes on that trip ahead of time, then all the time you would have wasted asking for directions immediately vanishes.&lt;br /&gt;&lt;br /&gt;In essence, that is what I did with Hiro. Hiro is an IOC container framework that reads the dependencies in your application ahead of time and actually &lt;span style="font-style:italic;"&gt;compiles&lt;/span&gt; a custom IOC container that knows how to create those dependencies from your application itself. &lt;span style="font-style:bold;"&gt;It uses absolutely no runtime reflection or runtime code generation&lt;/span&gt;, and since all your dependencies are discovered at compile time (that is, when the Hiro compiler runs), Hiro suffers zero performance penalties at runtime when instantiating your types.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Yes, you read that right:&lt;/span&gt; Hiro runs at 1:1 speed with a Plain/No DI configuration. Here's the results of the IOC container benchmark:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__BgjkW_AfhY/SeUbpE79siI/AAAAAAAAAFk/JDWa2PcPMsc/s1600-h/hiro_chart1.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 190px;" src="http://1.bp.blogspot.com/__BgjkW_AfhY/SeUbpE79siI/AAAAAAAAAFk/JDWa2PcPMsc/s320/hiro_chart1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5324692526949315106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;&lt;br /&gt;As you can see from the results above, the current crop of IOC containers (including LinFu) can only reach 2% of the speed of an application that does not use an IOC container. Now, let's take a look at Hiro's results:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__BgjkW_AfhY/SeUcm-iO8iI/AAAAAAAAAFs/2XHbfWUCYaE/s1600-h/hiro_chart2.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 194px;" src="http://1.bp.blogspot.com/__BgjkW_AfhY/SeUcm-iO8iI/AAAAAAAAAFs/2XHbfWUCYaE/s320/hiro_chart2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5324693590382670370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you don't believe it, then you can &lt;a href="http://hiro.googlecode.com/files/Performance.zi_"&gt;download and run the benchmarks yourself.&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Like LinFu, Hiro is licensed under the terms of the LGPL, and you can preview the source code &lt;a href="http://hiro.googlecode.com"&gt;at this site&lt;/a&gt;. I'll also be starting a &lt;a href="http://code.google.com/p/hiro-contrib/"&gt;Hiro-contrib&lt;/a&gt; project, so if you want to add your own extensions, just email me at marttub@hotmail.com and I'll be more than happy to anyone who is interested. Thanks! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1347962814343708249?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1347962814343708249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1347962814343708249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1347962814343708249'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/04/introducing-hiro-worlds-fastest-ioc.html' title='Introducing Hiro, the World&apos;s Fastest IOC Container, Part I: Design Diary'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__BgjkW_AfhY/SeUbpE79siI/AAAAAAAAAFk/JDWa2PcPMsc/s72-c/hiro_chart1.png' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-9140983147527711577</id><published>2009-02-28T21:40:00.000-08:00</published><updated>2009-02-28T22:05:09.662-08:00</updated><title type='text'>Common Service Locator Adapter for LinFu 2.0 Released!</title><content type='html'>Now that &lt;a href="http://www.codeproject.com/KB/cs/LinFu_IOC.aspx"&gt;LinFu.IOC 2.0&lt;/a&gt; is officially out, it's time to join the rest of the IOC container pack and let users try out LinFu without tying them to any specific IOC container API. The adapter for LinFu makes it possible to use the &lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;Common Service Locator interfaces&lt;/a&gt; to make your applications completely container-agnostic, so if you haven't tried LinFu yet, &lt;a href="http://linfu.googlecode.com/files/CommonServiceLocator.LinFuAdapter.zip"&gt;&lt;span style="text-decoration: underline;"&gt;download the adapter&lt;/span&gt;&lt;/a&gt;, and give it a shot. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-9140983147527711577?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/9140983147527711577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2009/02/common-service-locator-adapter-for.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9140983147527711577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9140983147527711577'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2009/02/common-service-locator-adapter-for.html' title='Common Service Locator Adapter for LinFu 2.0 Released!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3322215167469560443</id><published>2008-11-06T19:34:00.000-08:00</published><updated>2008-11-06T19:47:47.147-08:00</updated><title type='text'>LinFu.DynamicProxy 1.01 is now a part of NHibernate!</title><content type='html'>After passing all 1500+ tests in the NHibernate test suite, &lt;a href="http://groups.google.com/group/nhibernate-development/browse_thread/thread/c0452d5a16749e85"&gt;LinFu.DP1 will now be an official part&lt;/a&gt; of the NHibernate distribution!&lt;br /&gt;&lt;br /&gt;It's really an honor to be a part of a project that is so well-known in the .NET community, and I really want to thank the NHibernate team for giving LinFu a chance.&lt;br /&gt;&lt;br /&gt;There were a lot of developers who shied away from LinFu DP1 for the lack of unit tests, and this proves that LinFu DP 1.0 works as advertised, regardless of whether or not the tests existed. You now have 1500+ reasons to try it out without worrying about any problems, so &lt;a href="http://www.codeproject.com/KB/cs/LinFuPart1.aspx"&gt;give it a shot&lt;/a&gt;, and I'll always be here to answer your questions if anything breaks.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;[Disclaimer: That being said, I'm now a TDD convert&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;I no longer develop anything without&lt;/span&gt; &lt;span style="font-style: italic;"&gt;a batter&lt;/span&gt;y &lt;span style="font-style: italic;"&gt;of automated unit tests&lt;/span&gt;--&lt;span style="font-style: italic;"&gt;but it's still an big ego-booster to know that your code works exactly as it's supposed to work :) ]&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3322215167469560443?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3322215167469560443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/11/linfudynamicproxy-101-is-now-part-of.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3322215167469560443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3322215167469560443'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/11/linfudynamicproxy-101-is-now-part-of.html' title='LinFu.DynamicProxy 1.01 is now a part of NHibernate!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-6952102463086623381</id><published>2008-09-21T23:37:00.000-07:00</published><updated>2008-09-22T00:28:11.908-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu ioc versiontwo csharp'/><title type='text'>LinFu IoC 2.0 Reaches an Important Milestone</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Making the Grade&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After nearly two months of hard work, I am pleased to announce the impending release of LinFu.IoC v2.0! Today marks an amazing milestone in the development of LinFu's new IoC container because as of the latest build (revision 258), LinFu is the first IoC container framework to pass ALL tests in both the "MustHave" and the "ShouldHave" categories in &lt;a href="http://tinyurl.com/6l2ulh"&gt;the latest comparison&lt;/a&gt; between the following IoC Frameworks:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;AutoFac&lt;/li&gt;&lt;li&gt;Castle&lt;/li&gt;&lt;li&gt;LinFu&lt;/li&gt;&lt;li&gt;Ninject&lt;/li&gt;&lt;li&gt;StructureMap&lt;/li&gt;&lt;li&gt;Spring.NET&lt;/li&gt;&lt;li&gt;Unity&lt;/li&gt;&lt;/ul&gt;The feature lists might vary among these IoC frameworks, but Andrey's blog post does a great job of listing some of the features that an Inversion of Control container "must" have, in addition to the features that it "should" have", and I am proud to say that &lt;span style="font-weight: bold;"&gt;LinFu is the first IoC container to successfully implement every feature described in that blog post!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What this means is that LinFu.IoC (formerly Simple.IoC) has gone from an undocumented and untested inversion of control container to a fully documented, heavily tested, feature-laden container that is capable of performing all of the tasks that one would expect from a commercial-grade inversion of control container.&lt;br /&gt;&lt;br /&gt;In addition to the keeping the code as clean and as compact as possible, I spent countless hours ensuring that every single method, class, interface, property and enum is fully documented, regardless of whether or not that item was marked as public, internal, or private. I love my code and I love what I do, and I hope that shows in &lt;a href="http://code.google.com/p/linfu/wiki/BuildingLinFu2"&gt;the code that I write&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The best part about all this is that LinFu's IoC container framework weighs in at only 94KB, making it the smallest IoC framework among its brethen, with the Autofac container falling at a close 110KB.&lt;br /&gt;&lt;br /&gt;Within the next few weeks, I'll be publishing an article on CodeProject that details all the features that you can expect from LinFu.IoC 2.0, and I will time the release so that it coincides with the actual CodeProject article itself.&lt;br /&gt;&lt;br /&gt;Meanwhile, stay tuned!&lt;br /&gt;&lt;br /&gt;EDIT: I realize that this post is quite scant on details so if you want to dive straight into the LinFu.IoC source, you can just go &lt;a href="http://code.google.com/p/linfu/wiki/BuildingLinFu2"&gt;here&lt;/a&gt;. If you want to take a look at the IoC framework comparison project, &lt;a href="http://code.google.com/p/net-ioc-frameworks"&gt;click here&lt;/a&gt;. The code practically speaks for itself. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-6952102463086623381?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/6952102463086623381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/09/linfu-ioc-20-reaches-important.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6952102463086623381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6952102463086623381'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/09/linfu-ioc-20-reaches-important.html' title='LinFu IoC 2.0 Reaches an Important Milestone'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-8678376088043654852</id><published>2008-08-03T21:25:00.000-07:00</published><updated>2008-08-04T01:17:46.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu ioc versiontwo design dotnet csharp'/><title type='text'>Making Simple.IoC Even More Simple</title><content type='html'>Believe it or not, the following code represents most of LinFu.IoC's functionality when managing service instances:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// The SimpleContainer will handle unnamed services&lt;br /&gt;public class SimpleContainer : IContainer&lt;br /&gt;{&lt;br /&gt;   private readonly Dictionary&lt;type,&gt; _factories = new Dictionary&lt;type,&gt;();  &lt;br /&gt;&lt;br /&gt;   public virtual bool SuppressErrors&lt;br /&gt;   {&lt;br /&gt;       get; set;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual void AddFactory(Type serviceType, IFactory factory)&lt;br /&gt;   {&lt;br /&gt;       _factories[serviceType] = factory;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual bool Contains(Type serviceType)&lt;br /&gt;   {&lt;br /&gt;       return _factories.ContainsKey(serviceType);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual object GetService(Type serviceType)&lt;br /&gt;   {&lt;br /&gt;       object result = null;&lt;br /&gt;       if (!_factories.ContainsKey(serviceType) &amp;amp;&amp;amp; !SuppressErrors)&lt;br /&gt;           throw new ServiceNotFoundException(serviceType);&lt;br /&gt;&lt;br /&gt;       if (!_factories.ContainsKey(serviceType) &amp;amp;&amp;amp; SuppressErrors)&lt;br /&gt;           return null;&lt;br /&gt; &lt;br /&gt;       // Use the corresponding factory&lt;br /&gt;       // and create the service instance&lt;br /&gt;       var factory = _factories[serviceType];&lt;br /&gt;       if (factory != null)&lt;br /&gt;           result = factory.CreateInstance(this);&lt;br /&gt;&lt;br /&gt;       return result;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// The named container will handle named services&lt;br /&gt;public class NamedContainer : SimpleContainer, INamedContainer&lt;br /&gt;{&lt;br /&gt;   protected readonly Dictionary&lt;string,&gt;&gt; _namedFactories =&lt;br /&gt;       new Dictionary&lt;string,&gt;&gt;();&lt;br /&gt;&lt;br /&gt;   public virtual void AddFactory(string serviceName, Type serviceType, IFactory factory)&lt;br /&gt;   {&lt;br /&gt;       if (serviceName == string.Empty)&lt;br /&gt;       {&lt;br /&gt;           AddFactory(serviceType, factory);&lt;br /&gt;           return;&lt;br /&gt;       }&lt;br /&gt;       // Create the entry, if necessary&lt;br /&gt;       if (!_namedFactories.ContainsKey(serviceName))&lt;br /&gt;           _namedFactories[serviceName] = new Dictionary&lt;type,&gt;();&lt;br /&gt;&lt;br /&gt;       _namedFactories[serviceName][serviceType] = factory;      &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual bool Contains(string serviceName, Type serviceType)&lt;br /&gt;   {&lt;br /&gt;       // Use the standard IContainer.Contains(Type)&lt;br /&gt;       // if the service name is blank&lt;br /&gt;       if (serviceName == string.Empty)&lt;br /&gt;           return Contains(serviceType);&lt;br /&gt;&lt;br /&gt;       return _namedFactories.ContainsKey(serviceName) &amp;amp;&amp;amp;&lt;br /&gt;              _namedFactories[serviceName].ContainsKey(serviceType);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public virtual object GetService(string serviceName, Type serviceType)&lt;br /&gt;   {&lt;br /&gt;       // Used the other GetService method if&lt;br /&gt;       // the name is blank&lt;br /&gt;       if (serviceName == string.Empty)&lt;br /&gt;           return GetService(serviceType);&lt;br /&gt;&lt;br /&gt;       // Determine if the service exists, and&lt;br /&gt;       // suppress the errors if necessary&lt;br /&gt;       bool exists = Contains(serviceName, serviceType);&lt;br /&gt;       if (!exists &amp;amp;&amp;amp; SuppressErrors)&lt;br /&gt;           return null;&lt;br /&gt;&lt;br /&gt;       if (!exists &amp;amp;&amp;amp; SuppressErrors != true)&lt;br /&gt;           throw new NamedServiceNotFoundException(serviceName, serviceType);&lt;br /&gt;&lt;br /&gt;       var factory = _namedFactories[serviceName][serviceType];&lt;br /&gt;&lt;br /&gt;       // Make sure that the factory exists&lt;br /&gt;       if (factory == null)&lt;br /&gt;           return null;&lt;br /&gt;&lt;br /&gt;       return factory.CreateInstance(this);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/type,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/type,&gt;&lt;/type,&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, there's nothing special about this code. Some might even scoff at it since it's too minimalistic to be useful. After all, one might say that an IoC container has far more responsibilities than just object instantiation. &lt;a href="http://www.ninject.org/"&gt;Ninject&lt;/a&gt;, for example has features such as contextual binding and method interception. Surely this isn't all there is to LinFu.IoC's features, is it?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bend it like Ockham&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Despite the varying complexity of most (if not all) IoC containers in the field, logically speaking, the code listed above is the absolute minimum amount of code necessary to separate the instantiation of a service instance from its actual client code. When you request a service instance from a given IoC container (whether it be LinFu, Ninject or countless other containers out there), there has to be some point where the container has to decide if that service instance can be created, as well as manage the lifetime of that service once it is already out of the container. As most of us IoC container developers know, there's quite a lot more to a container than just managing the lifetime of its individual services. Creating the instance is only the first step, and I'll show you how LinFu version 2's new IoC container will implement the some of the same features without sacrificing its relatively-horizontal learning curve.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Pattern of Other Containers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Typically, these containers will use either property setter injection or constructor injection to autowire together all of the dependencies that an application might need during its lifetime. In addition, they might implement additional features such as interception, logging, and AOP. However, despite the differences in features among containers, there are two points where these features are commonly applied:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When a service is about to be created (e.g. constructor injection) or,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When a service is already instantiated (e.g. property setter injection, or interception)&lt;/li&gt;&lt;/ul&gt;This implies that a developer can add additional features to their respective IoC container simply by controlling the point where the service is going to be created as well as controlling the point where the service has been recently instantiated. In fact, if you can isolate those two points from the rest of the container, you can effectively add new features without affecting the rest of the code.&lt;br /&gt;&lt;br /&gt;Now the reason why LinFu's IoC container can get away with such simple code is because it actually delegates its factory methods to an instance of the IFactory interface:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;   public interface IFactory&lt;br /&gt;{&lt;br /&gt;    object CreateInstance(IContainer container);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;LinFu's IoC container uses each factory instance to determine how a service implementation should be instantiated, and each factory instance, in turn, is responsible for managing the lifetime of each component that it creates. With that in mind, the only thing that you have to do to extend LinFu's IoC container is to control how each factory creates its object instances (such as deciding which constructor and constructor arguments to use when implementing constructor injection) and control the instances that come out of each factory.&lt;br /&gt;&lt;br /&gt;For example, if I wanted to add interception to LinFu.IoC, all I have to do is wrap a Decorator around an IContainer (or INamedContainer) instance that wraps each service instance in a proxy:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class ContainerDecorator : IContainer&lt;br /&gt;{&lt;br /&gt;  private IContainer _container;&lt;br /&gt;  public ContainerDecorator(IContainer realContainer)&lt;br /&gt;  {&lt;br /&gt;       _container = realContainer;&lt;br /&gt;  }&lt;br /&gt;  // Other methods skipped for brevity&lt;br /&gt;  public object GetService(Type serviceType);&lt;br /&gt;  {&lt;br /&gt;       // Grab the service instance&lt;br /&gt;       var result = container.GetService(serviceType);&lt;br /&gt;    &lt;br /&gt;       // Wrap the instance, if possible&lt;br /&gt;       if (result != null)&lt;br /&gt;            return SomeProxyFactory.Wrap(result);&lt;br /&gt;&lt;br /&gt;       // Otherwise return the original instance&lt;br /&gt;       return result;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...and in the client code, using the additional decorator is as easy as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var container = new ContainerDecorator(new SimpleContainer());&lt;br /&gt;&lt;br /&gt;// Use the container somehow and transparently use the decorator to wrap the&lt;br /&gt;// result&lt;br /&gt;var service = container.GetService&amp;lt;ISomeServiceType&amp;gt;();&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, the implementation of LinFu.IoC is very straightforward, and there's really nothing exotic about the design. For those of you who were probably wondering why LinFu.IoC isn't using generics, here's the list of extension methods that completes the design:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  public static class ContainerExtensions&lt;br /&gt;  {&lt;br /&gt;      public static T GetService&lt;t&gt;(this IContainer container)&lt;br /&gt;          where T : class&lt;br /&gt;      {&lt;br /&gt;          var serviceType = typeof (T);&lt;br /&gt;          return container.GetService(serviceType) as T;&lt;br /&gt;      }&lt;br /&gt;      public static T GetService&lt;t&gt;(this INamedContainer container, string serviceName)&lt;br /&gt;          where T : class&lt;br /&gt;      {&lt;br /&gt;          return container.GetService(serviceName, typeof (T)) as T;&lt;br /&gt;      }&lt;br /&gt;      public static void AddFactory&lt;t&gt;(this INamedContainer container, string serviceName, IFactory&lt;t&gt; factory)&lt;br /&gt;      {&lt;br /&gt;          IFactory adapter = new FactoryAdapter&lt;t&gt;(factory);&lt;br /&gt;          container.AddFactory(serviceName, typeof (T), adapter);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public static void AddFactory&lt;t&gt;(this IContainer container, IFactory&lt;t&gt; factory)&lt;br /&gt;      {&lt;br /&gt;          IFactory adapter = new FactoryAdapter&lt;t&gt;(factory);&lt;br /&gt;          container.AddFactory(typeof(T), adapter);&lt;br /&gt;      }&lt;br /&gt;      public static void AddService&lt;t&gt;(this IContainer container, T instance)&lt;br /&gt;      {&lt;br /&gt;          container.AddFactory(typeof (T), new InstanceFactory(instance));&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Again, there's nothing unconventional in the design. In the end, it's the simplicity that matters most, and that is the difference that LinFu.IoC offers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-8678376088043654852?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/8678376088043654852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/08/making-simpleioc-even-more-simple.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8678376088043654852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8678376088043654852'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/08/making-simpleioc-even-more-simple.html' title='Making Simple.IoC Even More Simple'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3507277525494666444</id><published>2008-07-29T16:47:00.000-07:00</published><updated>2008-07-29T17:56:12.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu redesign rewrite versiontwo'/><title type='text'>The LinFu Reimplementation Plan, and Dogfooding</title><content type='html'>Before I hit the ground coding, let's go over some of the features that were in LinFu v1.0 that will also be in 2.0:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Dynamic Proxies&lt;/li&gt;&lt;li&gt;Late Binding / Multiple Dispatch&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Duck Typing&lt;/li&gt;&lt;li&gt;Mixins&lt;/li&gt;&lt;li&gt;Universal Event Handling&lt;/li&gt;&lt;li&gt;Closures with Lambda Arguments&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Design By Contract&lt;/li&gt;&lt;li&gt;AOP (static and dynamic weaving)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Inversion of Control / Dependency Injection&lt;/li&gt;&lt;li&gt;Adaptive Object Models&lt;/li&gt;&lt;li&gt;A MyXaml Engine Clone&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Aside from the fact that v1.0 has a fairly hefty feature list, one thing that I've noticed with the source is that despite those features, LinFu itself doesn't really use its own IoC or DbC facilities to improve the quality of its own code, and that's a wasted opportunity.&lt;br /&gt;&lt;br /&gt;With that in mind, I've decided to implement the following features first:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Inversion of Control / Dependency Injection&lt;/li&gt;&lt;li&gt;Dynamic Proxies&lt;/li&gt;&lt;li&gt;Design by Contract&lt;/li&gt;&lt;li&gt;Static AOP Weaving&lt;/li&gt;&lt;/ul&gt;Building an IoC/DI container will help enforce a separation of concerns, and using Design by Contract in tandem with TDD will eliminate over 90% of the bugs in the code. The reason why I'm also implementing the static AOP weaving and dynamic proxy generator first is that there has to be a way to transparently inject those contracts into a service instance using a dynamic proxy without having to clutter the original source code. In addition, using the static AOP weaving in a debug build will allow me to dynamically inject diagnostic code without affecting the actual release build.&lt;br /&gt;&lt;br /&gt;As for LinFu's Design by Contract v3.0, my goal is to make it injection-agnostic. That means that the library itself should be completely unaware of how it's actually being injected into a service instance. It will allow you to inject contracts using a 3rd-party dynamic proxy generator (such as Castle), and most importantly, it should make no distinction between LinFu's static AOP injection and its own proxy generator.&lt;br /&gt;&lt;br /&gt;Probably the most striking difference that you'll see between v1 and v2 is that&lt;span style="font-weight: bold;"&gt; LinFu will no longer be split into multiple projects&lt;/span&gt; (aside from PostWeaver.exe, and the MSBuild task for LinFu.AOP).  There might be some who might say that clumping all of LinFu into one DLL violates the principle of Separation of Concerns, but in practice, it will save you an untold amount of headaches when managing your project dependencies.&lt;br /&gt;&lt;br /&gt;I realize that rebuilding LinFu is a very tall order, and I'm putting my heart and soul into this one to make sure that it's the best code that I'll ever write. This is going to take some time to redo, and I'll keep posting more and more updates on my blog as time progresses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3507277525494666444?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3507277525494666444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/07/linfu-reimplementation-plan-and.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3507277525494666444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3507277525494666444'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/07/linfu-reimplementation-plan-and.html' title='The LinFu Reimplementation Plan, and Dogfooding'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-2166003486293020026</id><published>2008-07-28T19:50:00.000-07:00</published><updated>2008-07-28T20:14:41.689-07:00</updated><title type='text'>Behavior-Driven Development to the Rescue?</title><content type='html'>I've been trying to wrap my head around how I can increase LinFu's test coverage rate for over a week now, and I have to admit that doing DDT testing (aka TDD in reverse, or post-hoc unit testing) is much more difficult than its TDD counterpart.&lt;br /&gt;&lt;br /&gt;In contrast, TDD seems to apply a bottom-up approach to ensure that each component is functioning, and in LinFu's case, I'm going to need a top-down testing approach to ensure that all of LinFu's features work as advertised. My intent is to write each test as a specification for LinFu's behavior, and each one of these tests will ensure that LinFu behaves according to its specification.&lt;br /&gt;&lt;br /&gt;It's by no means perfect, but it's the only practical solution that I can apply to the existing code base without having to rewrite it.  At best, it seems like an ugly hack since I'll be effectively doing black box testing against LinFu instead of getting the 100% test coverage.&lt;br /&gt;&lt;br /&gt;The other alternative, of course, is that I can do a complete rewrite of LinFu (presumably version 2.0) from scratch. (It's not a pretty option, but then again, it's no better than having to do post-hoc unit testing).&lt;br /&gt;&lt;br /&gt;So here is my question for the developer community at large: Which option should I take, and why? If I do LinFu v2.0 with a 100% test coverage rate, will that up the adoption rate, or will LinFu v1.0 with specification tests added be sufficient enough to fix the test coverage problems?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-2166003486293020026?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/2166003486293020026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/07/behavior-driven-development-to-rescue.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2166003486293020026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2166003486293020026'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/07/behavior-driven-development-to-rescue.html' title='Behavior-Driven Development to the Rescue?'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-4305188397894913455</id><published>2008-07-22T13:11:00.000-07:00</published><updated>2008-07-22T13:33:45.442-07:00</updated><title type='text'>LinFu, and Biting the Testing Bullet.</title><content type='html'>Ok, I just have to admit it. LinFu still &lt;a href="http://www.nabble.com/LinFu--p17603741.html"&gt;&lt;span style="text-decoration: underline;"&gt;needs a lot more work&lt;/span&gt;&lt;/a&gt;. The test coverage is still 'awefully low', and despite the fact that I've kept my code clean and simple, it still doesn't take away from the fact that other programmers rely on automated unit tests to verify that your code works as advertised. I think Jeremy Miller said it best when he sent me this email:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;I'm giving you an A+ for the outright coolness of LinFu and the Comp Sci nature of things, but I'm questioning the software engineering.  To put it another way, I think you'll get far more adoption of LinFu if you have a better story to tell about the testing.  If you retrofit a battery of automated tests to at least cover the dynamic proxy and maybe the AOP, I'd be very interested in using LinFu inside my own StructureMap project.&lt;/blockquote&gt;&lt;br /&gt;Jeremy definitely has a point there, and in some ways, it's a bitter pill for me to swallow. The bottom line is that LinFu won't get widespread adoption unless I can increase its the test coverage rate. The irony here is that since I have a low test coverage rate from the start, I'll be subjecting myself to some of the same ills that I woefully complained about in other developers.&lt;br /&gt;&lt;br /&gt;With that in mind, I've decided to suspend all new development work on LinFu until I can resolve the test coverage issue. I will find a way to get to 100% unit test coverage, even if it means that I'll have to rewrite everything from scratch.&lt;br /&gt;&lt;br /&gt;LinFu is officially on lockdown mode, and I've got some major cleaning up to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-4305188397894913455?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/4305188397894913455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/07/linfu-and-biting-testing-bullet.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/4305188397894913455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/4305188397894913455'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/07/linfu-and-biting-testing-bullet.html' title='LinFu, and Biting the Testing Bullet.'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3698961266654186035</id><published>2008-06-07T08:15:00.000-07:00</published><updated>2008-06-07T08:30:05.745-07:00</updated><title type='text'>The Forced Hiatus and the Faulty Laptop.</title><content type='html'>Today I'll be sending my laptop back to the manufacturer for repairs, and that means all my development work (including LinFu) will be effectively suspended until I can get this issue resolved.  According to the &lt;a href="http://www.acer.com"&gt;manufacturer&lt;/a&gt;, the turnaround time should take about 7-10 business days (roughly two calendar weeks).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Meanwhile, the only 'hardware' that I'll have at my disposal will be Pen and Paper (tm), and I still have more than a few things lined up on the LinFu drawing board, even without a compiler.  Development is going to screech to a halt in the next few weeks, and then I'll be back with some pretty hefty updates to LinFu. Stay tuned :)&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3698961266654186035?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3698961266654186035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/06/forced-hiatus-and-faulty-laptop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3698961266654186035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3698961266654186035'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/06/forced-hiatus-and-faulty-laptop.html' title='The Forced Hiatus and the Faulty Laptop.'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-7410478430239287566</id><published>2008-03-31T16:20:00.000-07:00</published><updated>2008-03-31T17:16:37.391-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='orm'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Optimistic vs. Pessimistic Design: Which one do you practice?</title><content type='html'>Lately, I've been noticing a trend in some of the object-relational mapping (ORM) tools in the market place, and the pattern that's emerging is interesting, to say the least. &lt;br /&gt;&lt;br /&gt;In general, their feature sets seem to fall into one of these categories:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pessimistic Design&lt;/span&gt; - The designers don't know which features their users will actually use, so they decide to implement nearly *every* possible mapping feature and then leave the end-user to decide how to use their ORM. This approach gives the broadest amount of features but sacrifices simplicity for documentation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Optimistic Design&lt;/span&gt; - The designers assume that you're only going to use 20% of its functionality and implement 80% of the features that would be used in 100% of the mapping cases. They provide you with a general framework for the mapping and the change tracking, and they leave it to you (as the end user) to customize it to your needs. This approach makes the ORM easy to use, but the tradeoff is that it only implements a minimal feature set. The upside to this is that the code is so easy to use that it requires little to no documentation at all. It's practically self-documenting code.&lt;br /&gt;&lt;br /&gt;From what I've seen so far, a lot of ORM  implement pessimistic design, but very few actually implement the optimistic approach. Do the pessimistic designers assume that their end-users are incapable of implementing their own features, or is an optimistic approach too minimalistic to be useful at all?&lt;br /&gt;&lt;br /&gt;With this in mind, it's quite tempting for me to write an ORM that uses an optimistic design approach. There might be some value in having an ORM that lets you do your job in a few minutes without having to sift through dozens of pages of tutorials. I'm a big pundit for large feature sets, but in the end, there's no substitute for pure simplicity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-7410478430239287566?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/7410478430239287566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/03/optimistic-vs-pessimistic-design-which.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7410478430239287566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7410478430239287566'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/03/optimistic-vs-pessimistic-design-which.html' title='Optimistic vs. Pessimistic Design: Which one do you practice?'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-747177968368745845</id><published>2008-03-19T23:16:00.000-07:00</published><updated>2008-03-20T00:47:46.138-07:00</updated><title type='text'>LinFu.DynamicModel, MxClone, and the Art of Adaptive Object Models</title><content type='html'>&lt;span style="font-weight: bold;"&gt;I've done it! :)&lt;/span&gt; Both the LinFu.DynamicModel and the MxClone (the &lt;a href="http://www.myxmal.com"&gt;MyXaml&lt;/a&gt; Engine Clone) libraries are ready for production use, and I can't wait to get started on writing the CP articles for both libraries.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Tale of Two Approaches&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As I mentioned in previous posts, LinFu.DynamicModel allows you to dynamically create an entire object model in memory at runtime without having to recompile your application. With LinFu.DynamicModel, you can either construct the model directly through code, or you can use the MxClone to create the model for you, using XML markup. I'll briefly go over each approach in the following sections, but before I do that, let's take a look at the interface implementation that we're going to dynamically generate:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Canonical Approach: The Person Interface&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Let's suppose that I wanted to dynamically create a dynamic type that looks like the following interface:&lt;br /&gt;&lt;br /&gt;public interface IPerson&lt;br /&gt;{&lt;br /&gt;   int Age { get; set; }&lt;br /&gt;   string Name { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using LinFu.DynamicModel in Your Code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's how you can dynamically create a type that implements the IPerson interface:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// TypeSpec objects are type descriptions that can be modified at runtime&lt;br /&gt;TypeSpec personSpec = new TypeSpec()&lt;br /&gt;{&lt;br /&gt;   Name="PersonType",&lt;br /&gt; &lt;br /&gt;   // Notice the strongly-typed properties&lt;br /&gt;   Properties =&lt;br /&gt;   {&lt;br /&gt;       new Property&amp;lt;int&amp;gt;("Age"),&lt;br /&gt;       new Property&amp;lt;string&amp;gt;("Name")&lt;br /&gt;   },&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// This will return true&lt;br /&gt;bool isPerson = personSpec.LooksLike&amp;lt;IPerson&amp;gt;();&lt;br /&gt;var person = personSpec.CreateDuck&amp;lt;IPerson&amp;gt;();&lt;br /&gt;&lt;br /&gt;// Use the person object just like any other POCO&lt;br /&gt;person.Age = 18;&lt;br /&gt;person.Name = "Me";&lt;br /&gt;// ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks to C#'s 3.0 new language features, you can easily create a model in memory with LinFu in relatively few lines of code. What makes this particularly interesting, however, is the fact that as the given TypeSpec changes, all of the IPerson instances that rely on that TypeSpec automatically "change" their behavior to match the newly-modified Person TypeSpec.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using LinFu.DynamicModel with MxClone&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Needless to say, there's a myriad of things you can do with this sort of technology, &lt;span style="font-weight: bold;"&gt;but it gets better&lt;/span&gt;--you can describe the same model through XML, using a MyXaml-style syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;Root xmlns="LinFu.Reflection.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"&lt;br /&gt;xmlns:def="Definition"  xmlns:set="Setters"&amp;gt;&lt;br /&gt;  &amp;lt;TypeSpec def:Name="PersonType" Name="PersonType"&amp;gt;&lt;br /&gt;    &amp;lt;Properties&amp;gt;&lt;br /&gt;      &amp;lt;PropertySpec PropertyName="Name"&lt;br /&gt;                    PropertyType="System.String"&amp;gt;&lt;br /&gt;        &amp;lt;set:Behavior&amp;gt;&lt;br /&gt;          &amp;lt;PropertyBag/&amp;gt;&lt;br /&gt;        &amp;lt;/set:Behavior&amp;gt;&lt;br /&gt;      &amp;lt;/PropertySpec&amp;gt;     &lt;br /&gt;      &amp;lt;PropertySpec PropertyName="Age"&lt;br /&gt;                    PropertyType="System.Int32"&amp;gt;&lt;br /&gt;        &amp;lt;set:Behavior&amp;gt;&lt;br /&gt;          &amp;lt;PropertyBag/&amp;gt;&lt;br /&gt;        &amp;lt;/set:Behavior&amp;gt;&lt;br /&gt;      &amp;lt;/PropertySpec&amp;gt;&lt;br /&gt;     &lt;br /&gt;    &amp;lt;/Properties&amp;gt;&lt;br /&gt;  &amp;lt;/TypeSpec&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Root&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the XML syntax for MxClone is similar to MyXaml, with the exception of the &lt;span style="font-style:italic;"&gt;set:Behavior element&lt;/span&gt;. MxClone allows you to assign object references to properties without having to give it a specific reference name (e.g., {SomeName}), and in this case, the &lt;span style="font-style:italic;"&gt;set:Behavior&lt;/span&gt; element means that I'm assigning an object reference of type 'PropertyBag' to a property named "Behavior" on the PropertySpec type. (The PropertyBag class, in turn, is responsible for maintaining the state of each property on every given type instance--but for now, I'll save that for the upcoming LinFu article on CP)&lt;br /&gt;&lt;br /&gt;In essence, MxClone is actually constructing the same TypeSpec in memory using XML markup. Having the model specified in XML allows you to change it at runtime without recompiling the application, and that could come in handy if you need to change your business model with minimal downtime. Anyway, back to the markup...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;From XML to TypeSpec, in 15 Lines of Code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the XML markup, the next thing you might be wondering about is the client code: &lt;span style="font-style:italic;"&gt;exactly how do you convert that markup into a running TypeSpec?&lt;/span&gt; Here's how you do it:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Load the engine into the container&lt;br /&gt;string directory = AppDomain.CurrentDomain.BaseDirectory;&lt;br /&gt;SimpleContainer container = new SimpleContainer();&lt;br /&gt;Loader loader = new Loader(container);&lt;br /&gt;loader.LoadDirectory(directory, "*.dll");&lt;br /&gt;&lt;br /&gt;IMxEngine engine = container.GetService&lt;IMxEngine&gt;();&lt;br /&gt;&lt;br /&gt;// The instance holder will &lt;br /&gt;// store the object graph once&lt;br /&gt;// it's been instantiated by the engine&lt;br /&gt;IInstanceHolder holder = new DefaultInstanceHolder();&lt;br /&gt;string file = @"C:\YourDirectory\SimpleTypeSpecSample.xml";&lt;br /&gt;engine.Execute(file, holder);&lt;br /&gt;&lt;br /&gt;TypeSpec spec = holder.GetInstance&lt;TypeSpec&gt;("PersonType");&lt;br /&gt;bool isPerson = spec.LooksLike&lt;IPerson&gt;();&lt;br /&gt;&lt;br /&gt;// Use the person class normally&lt;br /&gt;IPerson person = spec.CreateDuck&lt;IPerson&gt;();&lt;br /&gt;person.Age = 18;&lt;br /&gt;person.Name = "Me";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the example above, I used the Simple.IOC container to instantiate the MxClone Engine. The engine, in turn, converted the XML markup into a working Person TypeSpec, and lastly, I used that same TypeSpec instance to create the IPerson instance. It's just that simple. :)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As you can see, there's quite a bit of development going on with LinFu.DynamicModel and LinFu.MxClone, and like everything else in the LinFu project, it will all remain under the LGPL license. I've put my heart and soul into this project, and hopefully, everyone will see that once the next set of LinFu articles comes out on CP. Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-747177968368745845?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/747177968368745845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/03/linfudynamicmodel-mxclone-and-art-of.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/747177968368745845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/747177968368745845'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/03/linfudynamicmodel-mxclone-and-art-of.html' title='LinFu.DynamicModel, MxClone, and the Art of Adaptive Object Models'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-2981429147998473324</id><published>2008-03-17T01:51:00.000-07:00</published><updated>2008-03-17T03:02:46.205-07:00</updated><title type='text'>Using Selective Method Weaving for LinFu.AOP</title><content type='html'>A while back, &lt;a href="http://www.codeproject.com/KB/cs/LinFuPart6.aspx?fid=997450&amp;amp;df=90&amp;amp;mpp=50&amp;amp;noise=3&amp;amp;sort=Position&amp;amp;view=Quick&amp;amp;select=2420108#xx2420108xx"&gt;someone asked me&lt;/a&gt; if there was a way to make LinFu.AOP weave only certain types of methods and properties, and at the time, LinFu.AOP wasn't capable of doing that--that is, until now.&lt;br /&gt;&lt;br /&gt;Here's how you do it. All you need to do is provide your own custom implementation of an interface named IMethodFilter and put that implementation in the same directory as LinFu.Aop.Weavers.Cecil.dll, and you're good to go. Here's a simple example:&lt;br /&gt;&lt;p&gt;[Implements(typeof(IMethodFilter), LifecycleType.OncePerRequest)]&lt;br /&gt;public class MySampleCustomFilter : IMethodFilter&lt;br /&gt;{&lt;br /&gt;  public bool ShouldWeave(MethodDefinition method)&lt;br /&gt;  {&lt;br /&gt;      // Intercept only public methods&lt;br /&gt;      return method.IsPublic;&lt;br /&gt;  }&lt;br /&gt;&lt;/p&gt;&lt;div id="qhide_41677" style="display: block;" class="qt"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;All you have to do is put that in a separate DLL and make sure that the assembly is located in the same directory as LinFu.Aop.Weavers.dll, and you can customize it to your heart's content. It's just that simple. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-2981429147998473324?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/2981429147998473324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/03/using-selective-method-weaving-for.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2981429147998473324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2981429147998473324'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/03/using-selective-method-weaving-for.html' title='Using Selective Method Weaving for LinFu.AOP'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-5761704482816413095</id><published>2008-03-13T01:41:00.000-07:00</published><updated>2008-03-13T02:39:39.037-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu adaptiveobjectmodels dotnet myxaml dynamicobject reflection'/><title type='text'>A Peek at LinFu.DynamicObject</title><content type='html'>Although it's been quite a while since my last post, LinFu has been coming along quite nicely with some recent additions. In the past month, I've managed to create two new things for LinFu:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    A Dynamic Typing System for &lt;a href="http://www.codeproject.com/KB/cs/LinFuPart2.aspx"&gt;LinFu.DynamicObject&lt;/a&gt;, and&lt;/li&gt;&lt;li&gt;    A MyXaml clone that will deserialize the DynamicModel from disk and load it into memory.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Current State of Affairs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In LinFu's current state,  you can only dynamically add properties and methods to DynamicObjects on a per-instance basis. Currently, there's no way to create a prototype for an entire set of DynamicObject instances and have all of those instances share the same conceptual prototype. For example, suppose that I wanted to create a Person type that looks something like this:&lt;br /&gt;&lt;br /&gt;public interface IPerson&lt;br /&gt;{&lt;br /&gt;    string Name { get; set; }&lt;br /&gt;    int Age { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In order to have a set of dynamic objects emulate a IPerson instance, I would have to manually generate a Name and an Age property on each dynamic object that I needed to use. While such a scenario might be acceptable if I only needed to use a few DynamicObjects, the story starts to become quite different if that small few suddenly becomes a few hundred thousand. Suffice to say, there's quite a cost in having to set up a couple hundred thousand dynamic objects in memory at runtime. There must be a better way to do this, and thus, LinFu.DynamicModel was born.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Build Your Own Model, All at Runtime&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;LinFu.DynamicModel allows you to create an in-memory type specification (or prototype) of what you want your DynamicObjects to look like. You can add or remove methods and properties to this specification at runtime, all without having to create a single DynamicObject. Any DynamicObject that is attached to that type specification will effectively have all the properties and methods of that spec. The best part about all this is that all changes you make to a spec at runtime will be reflected in every single DynamicObject that uses that type specification.&lt;br /&gt;&lt;br /&gt;For example, let's suppose that I wanted to create an implementation of the IPerson interface and have two DynamicObjects share the same conceptual Person type. Here's how it would look like:&lt;br /&gt;&lt;br /&gt;DynamicObject firstPerson = new DynamicObject();&lt;br /&gt;DynamicObject secondPerson = new DynamicObject();&lt;br /&gt;&lt;br /&gt;// Both of these LooksLike() calls will return false&lt;br /&gt;// since IPerson has yet to be implemented&lt;br /&gt;Console.WriteLine("Object #1: IsPerson? {0}", firstPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;Console.WriteLine("Object #2: IsPerson? {0}", secondPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;&lt;br /&gt;// Create a person type with only the Name property implemented&lt;br /&gt;TypeSpec personSpec = new TypeSpec();&lt;br /&gt;personSpec.AddProperty("Name", typeof(string));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;DynamicType personType = new DynamicType(personSpec);&lt;br /&gt;&lt;br /&gt;// Make both DynamicObjects act like the person type&lt;br /&gt;firstPerson += personType;&lt;br /&gt;secondPerson += personType;&lt;br /&gt;&lt;br /&gt;// Note: This still will return false since we haven't implemented the Age property&lt;br /&gt;Console.WriteLine("Object #1: IsPerson? {0}", firstPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;Console.WriteLine("Object #2: IsPerson? {0}", secondPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;&lt;br /&gt;// Finally, implement the age property so that both types look like an IPerson&lt;br /&gt;personSpec.AddProperty("Age", typeof(int));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// Note: Both DynamicObject instance calls to LooksLike() will now return true&lt;br /&gt;// since the type they refer to now implements IPerson&lt;br /&gt;Console.WriteLine("Object #1: IsPerson? {0}", firstPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;Console.WriteLine("Object #2: IsPerson? {0}", secondPerson.LooksLike&lt;iperson&gt;());&lt;br /&gt;&lt;br /&gt;// Use both instances normally as IPerson instances...&lt;br /&gt;IPerson first = firstPerson.CreateDuck&lt;iperson&gt;();&lt;br /&gt;IPerson second = secondPerson.CreateDuck&lt;iperson&gt;();&lt;br /&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;As you probably noticed from the example above, the only thing I needed to do was modify the TypeSpec instance and both DynamicObjects automatically changed their behavior to match the given TypeSpec. In theory,  this will allow you to effectively generate an entire object model in memory without having to recompile the application. In fact, the only thing you would need at this point is a reliable way to deserialize the object model from disk. At first, using the .NET BCL's serialization mechanisms might be the easiest way to do this, but LinFu.DynamicModel's metamodel heavily relies on interfaces to provide each method and property implementation, and those interfaces cannot be serialized to disk by the classes in the System.Runtime.Serialization namespace.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Legally Infeasible&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now, since MyXaml is very good at instantiating object graphs, and LinFu's DynamicModel is nothing but a metamodel object graph, the next logical step would be to use MyXaml, but there's just one problem--MyXaml is licensed under the GPL, not the LGPL, which means that MyXaml can't be used in commercial applications unless you obtain a commercial license from Marc Clifton, or you publish the source code to your own commercial applications. Since I'm committed to making all of LinFu available under the LGPL, I had no choice but to write my own MyXaml engine from scratch, and hopefully, I can cover that in my next blog post. For now, all I can say about my unnamed MyXaml clone is that it's some of the best code that I've ever written, and this one is definitely worth the wait.&lt;br /&gt;&lt;br /&gt;In the meantime, this should whet our appetite for what's to come in LinFu, and the future looks bright indeed.&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-5761704482816413095?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/5761704482816413095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/03/peek-at-linfudynamicobject.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5761704482816413095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5761704482816413095'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/03/peek-at-linfudynamicobject.html' title='A Peek at LinFu.DynamicObject'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-8222836477479181334</id><published>2008-02-06T20:10:00.000-08:00</published><updated>2008-02-06T20:18:04.748-08:00</updated><title type='text'>LinFu.DynamicObject and Dynamic Object Models</title><content type='html'>I've been playing around with LinFu.DynamicObject and I've discovered a way to implement a dynamic typing system that can be changed at runtime. That means that with LinFu.DynamicObject, you can assign it to a particular DynamicType instance and any DynamicObjects that depend on that same instance will actually &lt;span style="font-style: italic;"&gt;change&lt;/span&gt; their methods and properties at runtime to match that particular DynamicType!&lt;br /&gt;&lt;br /&gt;Adaptive Object Models, anyone? :)&lt;br /&gt;&lt;br /&gt;Dynamic Method Dispatch is one thing that LinFu can do very well, and pretty soon, you'll be able to reconfigure an entire object model in memory without having to recompile the application.&lt;br /&gt;&lt;br /&gt;Suffice to say, things are going to get interesting with LinFu as the series of articles progresses.&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-8222836477479181334?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/8222836477479181334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/02/linfudynamicobject-and-dynamic-object.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8222836477479181334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/8222836477479181334'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/02/linfudynamicobject-and-dynamic-object.html' title='LinFu.DynamicObject and Dynamic Object Models'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-9144164043455090086</id><published>2008-01-31T07:43:00.000-08:00</published><updated>2008-01-31T09:06:19.376-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvc mvp mvwithoutthep patterns eureka'/><title type='text'>The Model, View, and (Virtual) Presenter Pattern</title><content type='html'>&lt;a style="font-family: arial;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://blogs.ancestry.com/circle/wp-content/uploads/2006/11/talisman%20idea.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://blogs.ancestry.com/circle/wp-content/uploads/2006/11/talisman%20idea.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;One of the greatest weaknesses of the &lt;/span&gt;&lt;a style="font-family: arial;" href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVP/MVC pattern&lt;/a&gt;&lt;span style="font-family:verdana;"&gt; is that although the the model is completely separated from the view (and vice-versa), the view in the MVP pattern has to have a concrete dependency on its corresponding Presenter in order to function. At first, there doesn't seem to be a way to completely isolate all three components of the MVP pattern from each other, given that the view has to have a reference to a concrete presenter. The presenter, on the other hand, knows nothing about the concrete view, other than the IView interface that is implemented by the view itself; it's a one way dependency, and yet, something just doesn't 'feel' right here...&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;&lt;br /&gt;&lt;br /&gt;The Epiphany&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;br /&gt;...and then that's when the questions started to hit me: &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;Does the presenter even have to be a concrete presenter at all? Is it possible to replace a concrete presenter with an interface type, and what would that interface look like?&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;Are all presenters the same, or do they just all represent some sort of abstract concept that can't be centralized into a single common class?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-weight: bold;"&gt;My proposal for changing the MVP pattern is this:&lt;/span&gt; What if we convert the concept of the presenter from a concrete class to an &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;abstract&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;metaclass&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;? If we change the presenter from a concrete class to an abstract implementation of a concept, we can effectively eliminate the dependency between all three parts of the MVP triad. It might sound complex, but the implementation is actually quite simple. In this variant of the MVP pattern, we can completely eliminate the view's dependency on a concrete presenter by converting the concrete presenter dependency into a collection of interfaces that the view requires in order to function.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;&lt;br /&gt;&lt;br /&gt;A Quixotic Attempt&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;A naive approach would be to try to find a common interface to be implemented by &lt;/span&gt;&lt;span style="font-family:arial;"&gt; presenters, but this poses a problem--no two presenters will ever be exactly alike. A presenter that will handle a list view won't always have the same interface as a presenter that handles a date field. In addition, there might be presenters which might hold some business or validation logic that other presenters might not necessarily share. In other words, we're dealing with a situation where each presenter interface &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;allmust&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; be heterogenous for each view type, and that makes it difficult to group all of the presenters into a single interface that could be used by each view type.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;&lt;br /&gt;&lt;br /&gt;Dead End?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;At first, it might seem like we have no choice but to make each presenter concrete and customize each one of them to fit their corresponding views--but what if we refactored each one of these concrete presenters into multiple interface dependencies for each view? If you think about it, a concrete presenter is nothing but a collection of different responsibilities assigned to a concrete interface. For example, a DatePresenter class might have a few methods that check if the date value presented in the view is valid. The same DatePresenter class also might have methods which can persist the date value to the database. The crux of the concrete presenter in the MVP pattern is that the date view relies on this same DatePresenter to control its behavior. There's a one-way separation between the view and the presenter, and there has to be a way to completely isolate the presenter from the view itself.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;An Unnecessary Coupling&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;A view (for the most part) doesn't need a reference to a concrete presenter class as much as it needs a reference to the interfaces and responsibilities that each one of those interfaces represent. &lt;/span&gt;  &lt;span style="font-family:verdana;"&gt;In fact, if I were to refactor a concrete presenter, extract each one of its interfaces, and have each one of those interfaces represent a responsibility that the target view requires, it almost seems like I've converted the concrete presenter into a &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;de facto&lt;/span&gt; service container.&lt;br /&gt;&lt;br /&gt;Each presenter responsibility corresponds to a service, and each service corresponds to an interface type.  Since no two presenters are alike, one could even say that each presenter has a list of services that it offers to each view.   &lt;span style="font-family:verdana;"&gt;So for me, the next logical question is this: &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;If concrete presenters are nothing but de facto service containers, why not use a real service container (aka IoC container) and ditch the concrete dependency altogether?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;If a concrete presenter is actually nothing but a degenerate IoC container in disguise, then I can take each one of the view types and replace their concrete presenter dependencies with a single dependency--a dependency on &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;real&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; IoC container by itself.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;What makes this interesting is that in this variant of the MVP pattern, the 'P' in the MVP pattern no longer exists as a concrete class. The view's concrete dependency on the presenter has been supplanted by interface dependencies supplied by an IoC container. Using this scheme, the view knows nothing about the actual presenter concrete class, and the presenter knows nothing about the concrete view class. As an added bonus, we can even separate the presenter from the concrete model by having the presenter rely on interfaces supplied by the model, and vice versa.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;The best part about all this is that (aside from the interface dependencies) all three parts of the MVP triad are completely isolated from one another. The only dependency that all three parts of the MV(P) pattern share is the IoC container itself, and since most IoC containers are easily configurable by design (namely LinFu), this dynamically gives us complete control over all the dependencies of a given application.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;..&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;Note:&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; So far, all of this is just theory, and I have to write it down somewhere before I forget it. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;I think this pattern can help quite a lot of people, and hopefully I can test it soon.&lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-9144164043455090086?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/9144164043455090086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/model-view-and-virtual-presenter.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9144164043455090086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9144164043455090086'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/model-view-and-virtual-presenter.html' title='The Model, View, and (Virtual) Presenter Pattern'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1996754037554853614</id><published>2008-01-29T00:30:00.001-08:00</published><updated>2008-01-29T00:38:01.342-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whew aop linfu thankgoditstuesday'/><title type='text'>LinFu.AOP  Released!</title><content type='html'>After two long weeks of pounding away at the keyboard, I'm finally finished with the article for LinFu.AOP, and I'm proud to say that it's finally been released to the SVN repository for general use!&lt;br /&gt;&lt;br /&gt;So if you haven't downloaded a copy of LinFu.AOP yet, feel free to update your SVN copy to the latest revision as soon as possible--trust me, you don't want to miss this one! :)&lt;br /&gt;&lt;br /&gt;Now, if only CP can publish my article fast enough...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1996754037554853614?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1996754037554853614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfuaop-released.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1996754037554853614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1996754037554853614'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfuaop-released.html' title='LinFu.AOP  Released!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-7985259585958600679</id><published>2008-01-18T16:55:00.000-08:00</published><updated>2008-01-18T17:07:52.554-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='writethisblock'/><category scheme='http://www.blogger.com/atom/ns#' term='linfu'/><category scheme='http://www.blogger.com/atom/ns#' term='writersblock'/><category scheme='http://www.blogger.com/atom/ns#' term='writing'/><title type='text'>Writer's Block, or Write this Block?</title><content type='html'>I've been incredibly busy over the past few weeks so I haven't had time to update my blog until now. I've pretty much temporarily frozen any further development with LinFu (aside from bug fixes) until I can get the Part VI article out the door and released to CodeProject. I don't know why, but lately I've caught a really bad case of writer's block. It seems like there's so many topics that I need to cover for Part VI, but I can't seem to flesh out all the details without reading through the current draft and finding glaring omissions in the documentation itself. Call me an obsessive perfectionist, but I won't release any article unless I know that it meets my standards.&lt;br /&gt;&lt;br /&gt;I can't really quantify it, but my intuition is telling me something wrong here--and I won't rest until I can finally get this article fixed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-7985259585958600679?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/7985259585958600679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/writers-block-or-write-this-block.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7985259585958600679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7985259585958600679'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/writers-block-or-write-this-block.html' title='Writer&apos;s Block, or Write this Block?'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3074930747326947467</id><published>2008-01-05T18:03:00.000-08:00</published><updated>2008-01-12T04:59:19.124-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu aop notes dotnet'/><title type='text'>A Familiar Story, Told by LinFu.AOP</title><content type='html'>Here's a simple story that shows what one can do with LinFu.AOP. Note the code listing below:&lt;br /&gt;&lt;br /&gt;public class Person&lt;br /&gt;{&lt;br /&gt;    public string Name { get; set; }&lt;br /&gt;    public int Age { get; set; }&lt;br /&gt;    public void Speak()&lt;br /&gt;    {&lt;br /&gt;            Console.WriteLine("Hello, World!");&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;        &lt;br /&gt;public class Demon&lt;br /&gt;{&lt;br /&gt;    public string Name&lt;br /&gt;    {&lt;br /&gt;        get { return "Captain Howdy"; }&lt;br /&gt;        set { throw new InvalidOperationException("Are you crazy??"); }&lt;br /&gt;    }&lt;br /&gt;    public int Age&lt;br /&gt;    {&lt;br /&gt;        get { return 999999; }&lt;br /&gt;        set {  }&lt;br /&gt;    }&lt;br /&gt;    public void Possess(Person person)&lt;br /&gt;    {&lt;br /&gt;        DynamicObject dynamic = new DynamicObject(this);&lt;br /&gt;        dynamic.Attach(person);&lt;br /&gt;    }&lt;br /&gt;    public void Deposses(Person person)&lt;br /&gt;    {&lt;br /&gt;        MakeHeadSpin();&lt;br /&gt;        VomitGreenStuff();&lt;br /&gt;        throw new InvalidOperationException("Fat chance, buddy!");&lt;br /&gt;    }&lt;br /&gt;    public void MakeHeadSpin()&lt;br /&gt;    {&lt;br /&gt;        // ...&lt;br /&gt;    }&lt;br /&gt;    public void VomitGreenStuff()&lt;br /&gt;    {&lt;br /&gt;        // ...&lt;br /&gt;    }&lt;br /&gt;    public void Speak()&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine("This girl is mine!");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            // There once was a nice little girl...&lt;br /&gt;            Person girl = new Person() { Name = "Linda Blair", Age = 6 };&lt;br /&gt;&lt;br /&gt;            // Who spoke in a soft voice..&lt;br /&gt;            girl.Speak();&lt;br /&gt;&lt;br /&gt;            // Until one day, she played with some crazy oija board named 'LinFu.AOP', and&lt;br /&gt;            // then everything changed...&lt;br /&gt;            Demon demon = new Demon();&lt;br /&gt;            demon.Possess(girl);&lt;br /&gt;            IModifiableType modified = girl;&lt;br /&gt;            girl.IsInterceptionEnabled = true;&lt;br /&gt;&lt;br /&gt;            // Then some devoted priest came along and spoke with the girl, and she said:&lt;br /&gt;            girl.Speak();&lt;br /&gt;&lt;br /&gt;            // He took pity on the girl, and tried to free her from the demon.&lt;br /&gt;            demon.Deposses(girl);&lt;br /&gt;&lt;br /&gt;            // The demon resisted, but the priest was smart, and in the end,&lt;br /&gt;            // he subdued the demon.&lt;br /&gt;            girl.IsInterceptionEnabled = false;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            // ..the end&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Devil in the Details&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now, if you look at that code listing above, you'll notice that the Person class has no idea that it's being intercepted at all. In fact, poor little Linda doesn't know the trouble she's getting into. The Demon class was able to possess Person types because LinFu.AOP modified the Person class to allow itself to be dynamically intercepted at runtime, all without the knowledge of the said victim.&lt;br /&gt;&lt;br /&gt;What makes this interesting, however, is that interception can be easily turned on or off depending on the value of the IsInterceptionEnabled property. In fact, if interception is turned off, the Person class will behave just like any other normal person without any performance penalties that are typically incurred by pass-through interception. If interception is turned on, of course, you'll be bound to have some performance overhead incurred, but the added flexibility bonus is staggering. With the slight decrease in performance, you can effectively take over the implementation of the entire class at runtime, and you can even customize it on a per-instance basis.&lt;br /&gt;&lt;br /&gt;Think about it. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3074930747326947467?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3074930747326947467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/familiar-story-told-by-linfuaop.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3074930747326947467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3074930747326947467'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/familiar-story-told-by-linfuaop.html' title='A Familiar Story, Told by LinFu.AOP'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-7839976603004952799</id><published>2008-01-05T17:16:00.000-08:00</published><updated>2008-01-05T18:03:30.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eureka linfu aop byjovewehaveit greatscott omg dotnet'/><title type='text'>LinFu AOP, Reinvented</title><content type='html'>After four days of coding and refactoring, I've done it! I've managed to rewrite the original version of LinFu.AOP to address all of the issues that I mentioned in previous posts, and now I only need to write the MSBuild task and the command-line weaver before I can go ahead and start working on the CP article. I know that LinFu.AOP has been vaporware as of late, but I can guarantee you that this is definitely worth the wait.&lt;br /&gt;&lt;br /&gt;Aside from the &lt;a href="http://plaureano.blogspot.com/2008/01/linfuaop2-specifications-and.html"&gt;features&lt;/a&gt;  that I mentioned earlier in this blog, LinFu.AOP will add some interesting features to the LinFu Framework, such as:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Even &lt;span style="font-style:italic;"&gt;simpler&lt;/span&gt; Simple.IOC integration&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With LinFu.AOP, you no longer have to even reference Simple.IOC.dll in your application to use the container. For example, instantiating an IDbConnection type from a SimpleContainer instance will be easy as:&lt;br /&gt;&lt;br /&gt;IDbConnection myConnection = New&lt;IDbConnection&gt;.Instance;&lt;br /&gt;&lt;br /&gt;...that's it! Behind the scenes, LinFu.AOP will actually intercept the call made to the following class:&lt;br /&gt;&lt;br /&gt;public class New&lt;T&gt;&lt;br /&gt;{&lt;br /&gt;    public static T Instance&lt;br /&gt;    {&lt;br /&gt;        get { throw new NotImplementedException(); }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now, believe it or not, &lt;span style="font-style:italic;"&gt;the code listing above is the actual implementation&lt;/span&gt; of the New&lt;T&gt; class. What I'm actually doing is using LinFu.AOP to redirect the request for an IDbConnection instance to an appropriate factory method (in this case, the Simple.IOC container). What makes this even more interesting is that it employs the same type of XCOPY-style configuration that you would expect from LinFu; it means that if you wanted to inject any more dependencies into the container, all you have to do is drop the new dependencies into the directories, and the container will rebuild itself and that dependency will be available in the next New&lt;T&gt;.Instance call! &lt;br /&gt;&lt;br /&gt;LinFu.DynamicProxy 'Submersion'&lt;br /&gt;&lt;br /&gt;One of LinFu.DynamicProxy's weaknesses is that its interceptor instances can only be bound to an unsealed type with all of its public methods marked virtual. &lt;span style="font-weight:bold;"&gt;With LinFu.AOP, that limitation no longer applies&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;LinFu.AOP allows LinFu.DynamicProxy interceptors to intercept methods and properties on type instances &lt;span style="font-weight:bold;"&gt;without even using the proxy generator itself&lt;/span&gt;. This means that when LinFu.AOP intercepts a method call done against a target type, there is no intermediate proxy doing the interception. LinFu.AOP rewrites the IL in your method body and redirects it to your interceptor, all at runtime. You can even &lt;span style="font-weight:bold;"&gt;reuse&lt;/span&gt; the old method implementation as if you were still using DynamicProxy.&lt;br /&gt;&lt;br /&gt;One could even say that the inteceptor has 'submerged' itself into the type implementation because the interceptor can still intercept any method on any given type as if it were still attached to the proxy--however, what makes it 'submerged' is the fact that you're actually using the true object instance itself!&lt;br /&gt;&lt;br /&gt;To take this concept even further, LinFu.AOP supports two levels of method interception: Class-Based, and Instance-Based.&lt;br /&gt;&lt;br /&gt;This means that you can either intercept a particular method across all instances of a given type, OR you can actually customize the method replacement (or interceptor) based on the current instance that you're using. Think about that for a moment...&lt;br /&gt;&lt;br /&gt;...and while you're thinking about that, I'm going to go back and polish this thing up. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-7839976603004952799?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/7839976603004952799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfu-aop-reinvented.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7839976603004952799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/7839976603004952799'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfu-aop-reinvented.html' title='LinFu AOP, Reinvented'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-9204652573982371124</id><published>2008-01-02T15:01:00.000-08:00</published><updated>2008-01-02T15:16:55.568-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linfu aop redesign notes dotnet'/><title type='text'>On Donuts and Method Interception Styles</title><content type='html'>To keep the ball rolling, LinFu.AOP2 will support the following styles of method interception:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Donut Interception&lt;/span&gt; - This means that when a method is intercepted, its original implementation (a.k.a. its method body) will be left intact, but LinFu.AOP2 will inject additional behavior &lt;span style="font-weight:bold;"&gt;around&lt;/span&gt; the original method body--hence, the donut moniker. This can be useful if you want to inspect the input and the output of a given method without altering its implementation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Donut Hole Interception&lt;/span&gt; - This means that when a method is intercepted, its original implementation is completely discarded and replaced with a different implementation altogether. &lt;br /&gt;&lt;br /&gt;To make this interesting,&lt;span style="font-weight:bold;"&gt; LinFu.AOP allows both styles of interception to overlap each other, all at runtime&lt;/span&gt;. That means you can inject code 'around' a method body, and you can even replace that method body with something else altogether. Needless to say, this new framework offers a staggering amount of power not readily available in any .NET language today, and the possibilities with it are truly limitless.&lt;br /&gt;&lt;br /&gt;(Meanwhile, all this talk of donuts is making me hungry, so I'm off to breakfast...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-9204652573982371124?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/9204652573982371124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/on-donuts-and-method-interception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9204652573982371124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9204652573982371124'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/on-donuts-and-method-interception.html' title='On Donuts and Method Interception Styles'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1047454912169112878</id><published>2008-01-02T14:07:00.000-08:00</published><updated>2008-01-02T15:00:58.100-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reinventingthewheel prototypes aop linfu redesign design'/><title type='text'>LinFu.AOP2 Specifications and Requirements</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.letusinsureyou.com/lightbulb%20idea.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px;" src="http://www.letusinsureyou.com/lightbulb%20idea.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;In general, LinFu.AOP2 must meet the following requirements:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pervasive Method Interception&lt;/span&gt; - It must intercept both instance and static methods on all types, regardless of whether or not the target types are sealed or unsealed. This also includes non-virtual methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Type Initialization&lt;/span&gt; - It must intercept constructor calls and allow its users to perform custom initialization steps to each type that is created in memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;No Proxy Required&lt;/span&gt; - It must do all of the above interception operations without using any form of DynamicProxy generator (whether it is LinFu, Castle, or whatnot).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Completely Transparent&lt;/span&gt; - The target library should not even be aware of any changes made to it by the AOP library. When I look at the source for the target library, there should be no trace or reference to any of the changes made by the new AOP library. In short, all changes should be completely invisible.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;No Attributes Required&lt;/span&gt; - This means that it should not force the end-user to use .NET attributes at all to specify where any code should be inserted or injected. I might sound like a purist, but in my opinion, the very act of scattering attributes across your application is crosscutting in itself--and that's exactly what AOP is trying to avoid, and I'll do my best to avoid that as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Runtime Injection and Interception&lt;/span&gt; - LinFu.AOP2 must allow the end user developer to arbitrarily inject or insert any piece of code into an application, all at runtime, not compile time. This is a huge contrast to PostSharp, which only allows you to inject new method behavior at post-build (compile) time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Language-Independent&lt;/span&gt; - It must be able to be used from nearly any .NET language, regardless of the target language's syntax.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Strong Name Signature Stripping&lt;/span&gt; - It *should* be able to strip the strong name signature right off of any signed assembly. Given the controversial nature of this particular topic, this feature is completely optional.&lt;br /&gt;&lt;br /&gt;Fortunately, since LinFu.AOP1 met seven out of eight of these requirements (that is, everything but the strong name signature stripping), most of the implementation research has already been completed. The only thing left to do is to refine the implementation, and hopefully, it will be ready for an article release on CodeProject. &lt;br /&gt;&lt;br /&gt;I'll post as much design notes as I can on this blog to keep everyone posted. Once I come up with any breakthroughs, I'll post some code on this blog for everyone to peruse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1047454912169112878?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1047454912169112878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfuaop2-specifications-and.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1047454912169112878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1047454912169112878'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/linfuaop2-specifications-and.html' title='LinFu.AOP2 Specifications and Requirements'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-6141805642675035487</id><published>2008-01-01T15:55:00.000-08:00</published><updated>2008-01-01T16:05:28.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reinventingthewheel prototypes aop linfu'/><title type='text'>Back to the Drawing Board</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.public-works.org/images_new/feature_reinvent_innovation.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px;" src="http://www.public-works.org/images_new/feature_reinvent_innovation.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Although my working prototype of LinFu.AOP has some stunning features such as pervasive &lt;br /&gt;method interception and transparent code injection, at this point, it doesn't quite yet meet my quality standards for something that I would release to the general public, so I'm going to scrap it and start off from scratch.&lt;br /&gt;&lt;br /&gt;Queue LinFu.AOP, take two...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-6141805642675035487?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/6141805642675035487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2008/01/back-to-drawing-board.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6141805642675035487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6141805642675035487'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2008/01/back-to-drawing-board.html' title='Back to the Drawing Board'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-9182337433764923541</id><published>2007-12-22T13:59:00.000-08:00</published><updated>2009-04-11T03:09:32.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='simplicity'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='codeproject'/><category scheme='http://www.blogger.com/atom/ns#' term='kiss'/><category scheme='http://www.blogger.com/atom/ns#' term='general'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>The Admission That Every Developer Must Make...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/__BgjkW_AfhY/R223cejUlsI/AAAAAAAAABw/TgHmcSvEpBU/s1600-h/incompetence.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/__BgjkW_AfhY/R223cejUlsI/AAAAAAAAABw/TgHmcSvEpBU/s400/incompetence.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5146971649019778754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;...is that no matter how great you think your code is, &lt;span style="font-weight:bold;"&gt;it ultimately sucks&lt;/span&gt;. At some point in time, the "great" code that you think you're writing will ultimately cause pain on somebody else.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Gift That Keeps on Giving&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Code is a lot of fun to write, but the more code you write, the more suffering you inflict upon others. I can't begin to stress enough that &lt;span style="font-weight:bold;"&gt;the mere presence of code itself is a symptom of a problem&lt;/span&gt;. It means that you had to write something because whatever requirements that you had to meet couldn't be done using the existing code that you have at your disposal. In other words, you're writing code to solve a preexisting deficiency, whether it was a deficiency on someone else's part, or your own.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Isn't it i.Ronic()?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This has to be the greatest irony of software development: we (as developers) write code to solve other people's problems, but the more code we write, the more problems we inflict on other developers that eventually have to maintain our code. In the end, someone out there has to maintain that 'wonderful' solution that you thought you wrote in yesteryear. In the end, someone else has to write their own version of your library because you had some deficiency in it that was too complicated to fix. That new library, in turn, will eventually fail to solve another problem, causing another developer to write &lt;span style="font-style:italic;"&gt;another application&lt;/span&gt; to solve the new problem that couldn't be fixed using any other means.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Path of Suffering&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's a vicious cycle that never ends, and at some point, this pain of maintenance that we inflict on other developers must somehow end. A naive solution to this would be to stop writing code altogether, but it still doesn't solve the problems that we as developers ultimately need to solve. We still need to write code in our daily lives to pay the bills, and people will still need us to write software so that they don't have to do all their work by hand. In other words, it's a necessary evil that perpetuates itself. We cannot avoid the fact that our jobs (by definition) require us to write more and more code--and that's exactly the problem. &lt;span style="font-weight:bold;"&gt;Code begets even more code, causing the suffering to continue&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Code Nirvana, and the Path of Enlightenment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This cycle seems complicated and nearly impossible to fix, but the solution is ridiculously simple: &lt;span style="font-style:italic;"&gt;write less code&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;In general, there are a few ways to do write less code:&lt;br /&gt;&lt;br /&gt;-Design Patterns.&lt;br /&gt;-Refactoring.&lt;br /&gt;-Keeping it simple.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Design Patterns - A Panacea?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, there are some people out there that think that implementing a particular design pattern automatically leads to less code. That's not always the case. The more patterns you add to your application, the more suffering you inflict on those who have to maintain it and those who use it, and that still doesn't solve the problem of ending the suffering altogether.&lt;br /&gt;&lt;br /&gt;It means that if you need to use multiple design patterns in your applications, more often than not, your code is far too complicated to write using the simplest possible means. Design patterns exist to &lt;span style="font-style:italic;"&gt;simplify&lt;/span&gt; code, and if you find yourself scrolling through thousands and thousands of lines of code in multiple source files to figure out how your 'cool' pattern works, then you're defeating the original purpose of having those design patterns altogether: &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;simplicity&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;if (complexity == null) { // Cool! }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For me, it's always a pleasure to see someone else write something so simple that I don't have to waste any more than five minutes trying to figure out how to use their code. Unfortunately, such moments rarely ever occur for me, and more often than not, I find myself having to wade through pages and pages of their code or documentation (or both) to do something that's supposedly 'simple' to do using their software--and that assumes that they even write documentation at all.&lt;br /&gt;&lt;br /&gt;Yet again, it becomes even more ironic because it seems that the same developers who write documentation for their code are actually compensating for the fact that their code is so complicated that it needs documentation in the first place. Even I have to admit that &lt;a href="http://www.codeproject.com/KB/cs/LinFuPart1.aspx"&gt;I'm guilty of this myself&lt;/a&gt;, given that I wrote a series of articles that describes how to use LinFu. It's certainly not as simple as I would like it to be, and in my opinion, admitting that it can be made simpler (or more importantly, &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;admitting that it sucks&lt;/span&gt;&lt;/span&gt;) is the first step in becoming a better developer. In any case, the same principle for having more and more code is also true for having more and more documentation: &lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;More documentation is a symptom of complexity. It's not a feature--it's a liability&lt;/span&gt;&lt;/span&gt;. So if design patterns themselves don't necessarily mean simplicity, what about Refactoring? Does that solve the problem?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;I Code, You Fix It (Later)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Refactoring is certainly one of the best things you can do for your application(s), and it definitely can reduce the coding "footprint" that you impose on developers who will eventually maintain your code. However, at the risk of sparking some controversy, if you're the initial developer, &lt;span style="font-style:italic;"&gt;refactoring is actually something that you should avoid&lt;/span&gt;, and I'll explain why.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hold Your Pitchforks...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before I become labeled as a madman, let's analyze the etymology of the word "refactoring". The Greek/Latin root of the prefix "Re" roughly translates to "again", and the word "factoring" (&lt;a href="http://dictionary.reference.com/browse/factoring"&gt;according to dictionary.com&lt;/a&gt;) means:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;2. the act or process of separating an equation, formula, cryptogram, etc., into its component parts.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The meaning of the word "factoring" (in this context) is effectively the process of designing your application. In other words, when you combine those two small phrases together into the word "refactoring", it means that your design was faulty enough to warrant a redesign of your code. So my only criticism with refactoring is this--refactoring isn't a preventive measure. &lt;span style="font-style:italic;"&gt;It's a reactive measure that everyone (including myself) undertakes when they slowly realize that their code really, really sucks&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So when I say that you should "avoid" refactoring, what I'm actually saying is that you should avoid having to make your code so complicated that it needs to be refactored in the first place. Refactoring, in practice, is an absolute necessity; however, you can avoid refactoring altogether by making your code so simple that it makes refactoring seem ridiculous. For example, when was the last time you had to debug a property getter/setter like:&lt;br /&gt;&lt;br /&gt;public int SomeProperty&lt;br /&gt;{&lt;br /&gt;   get { return _someProperty;  }&lt;br /&gt;   set { _someProperty = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Dubya-Tee-Eff?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above example might seem too simplistic--and some people would even scoff at the concept of debugging something so simple--&lt;span style="font-style:italic;"&gt;but that's the idea&lt;/span&gt;. It's so simple that you don't have to worry about how it works--&lt;span style="font-weight:bold;"&gt;it just works&lt;/span&gt;. You can criticize it all you want for being so simple, but it probably took you less than a second in your mind to make a judgment about it, and move on to something else more useful. In contrast, it naturally takes several hours (or even days, weeks, or months) to solve something more complex. &lt;span style="font-weight:bold;"&gt;The point here is that having simplicity precludes the need to refactor and (thus) redesign your application&lt;/span&gt;, and that something I'll talk about next.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The Best Code Ever Written&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The best code that I have ever seen in my life is certainly not my own; however, it's really easy to remember, and you can find it in between the two comment lines below:&lt;br /&gt;&lt;br /&gt;// ---begin best code ever written--&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// ---end best code ever written--&lt;br /&gt;&lt;br /&gt;No, I haven't gone crazy. You might be saying to yourself that there is no code between those two comment lines. &lt;span style="font-weight:bold;"&gt;You're right&lt;/span&gt;.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;The best code ever written is code that doesn't have to be written at all&lt;/span&gt;&lt;/span&gt;. Ultimately, it's being able to solve a problem without having to resort to writing code in the first place. There's literally no code to maintain, meaning that no poor sap has to cleanup my code in the long run. No suffering, no pain, and no mess. It's simply beautiful.&lt;br /&gt;&lt;br /&gt;For those short of this lofty goal of not having to write code (including myself), however, my only advice is this: &lt;span style="font-weight:bold;"&gt;Simplicity is the ultimate design pattern&lt;/span&gt;. If you write it simple the first time, you won't have to worry about refactoring it because you "fudged" it with several other not-so-simple design patterns. You'll be able to rest well knowing that your code won't cause someone else to curse your name at 4am (your local time), and in the end, that is truly sweet indeed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-9182337433764923541?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/9182337433764923541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/12/admission-that-every-developer-must.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9182337433764923541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/9182337433764923541'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/12/admission-that-every-developer-must.html' title='The Admission That Every Developer Must Make...'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/__BgjkW_AfhY/R223cejUlsI/AAAAAAAAABw/TgHmcSvEpBU/s72-c/incompetence.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-6676086345235438439</id><published>2007-12-13T14:21:00.000-08:00</published><updated>2007-12-13T14:26:31.775-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><title type='text'>Holiday Hiatus.</title><content type='html'>I'll be taking some time off for the holidays, so that means development for the LinFu framework is going to take a break for the holiday season, as well. When I come back after the new year, things will again go back to full speed. Happy Holidays!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-6676086345235438439?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/6676086345235438439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/12/holiday-hiatus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6676086345235438439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/6676086345235438439'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/12/holiday-hiatus.html' title='Holiday Hiatus.'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-2228553963547957208</id><published>2007-12-09T15:00:00.000-08:00</published><updated>2007-12-09T15:16:47.233-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='notinventedhere'/><category scheme='http://www.blogger.com/atom/ns#' term='nih'/><category scheme='http://www.blogger.com/atom/ns#' term='mono.cecil'/><category scheme='http://www.blogger.com/atom/ns#' term='ceciltheuglywife'/><category scheme='http://www.blogger.com/atom/ns#' term='nottheoldhagagain'/><title type='text'>My Love-Hate Relationship with Mono.Cecil</title><content type='html'>I managed to fix the bug from my previous rant about Mono.Cecil, and I've even managed to implement some jaw-dropping method interception capabilities using that library. I can now intercept any method from nearly any .NET assembly, regardless of whether or not that method is static, sealed, and even non-virtual. The only problem with this library is that the more I explore its capabilities, the more I find myself becoming too dependent on Mono.Cecil. It might take me another year of research just to get LinFu.Reflection.Emit up and running, so for now, I really don't have any other viable alternatives to use (other than Mono.Cecil, of course). &lt;br /&gt;&lt;br /&gt;It's ultimately a 'marriage of convenience' of sorts, and until I can make an alternative of my own, a figurative divorce is not an option.&lt;br /&gt;&lt;br /&gt;One of these days, my bouts of NIH (Not Invented Here) syndrome are either going to either going to make me rich, or just plain insane, and since the first option doesn't seem so possible, I think the 'insanity' option just might get the best of me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-2228553963547957208?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/2228553963547957208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/12/my-love-hate-relationship-with.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2228553963547957208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/2228553963547957208'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/12/my-love-hate-relationship-with.html' title='My Love-Hate Relationship with Mono.Cecil'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-1965511284574747260</id><published>2007-12-04T17:08:00.000-08:00</published><updated>2007-12-04T17:18:41.924-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='wishlist'/><category scheme='http://www.blogger.com/atom/ns#' term='futurefeatures'/><category scheme='http://www.blogger.com/atom/ns#' term='dlr'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamiclanguages'/><title type='text'>A feature that I would love to see in future IDEs...</title><content type='html'>With all this talk of type inferencing on the horizon and with the coming of Dynamic Languages to the .NET platform, one feature that I would love to see in VS.NET is something I call it Intellisense, with &lt;b&gt;"Type Prediction"&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;The concept is actually quite simple. Since dynamic languages themselves have the ability to dynamically modify their types at runtime, it would be nice if the compiler were smart enough to "predict" (at compile time) which methods and properties that a class might have at run time. So, for example, if I had a class called MyDynamicClass, and if at some point in the the class' lifetime, I wanted to add a method called DoSomething(), then the IDE should be able to effectively guess which parts of the code have a DoSomething() method available and give me an intellisense listing of all its signatures. &lt;br /&gt;&lt;br /&gt;Then again, since we're only at the cusp of even beginning to use dynamic languages on the CLR, it'll be quite a while before anyone picks up on this idea. Oh well. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-1965511284574747260?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/1965511284574747260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/12/feature-that-i-would-love-to-see-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1965511284574747260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/1965511284574747260'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/12/feature-that-i-would-love-to-see-in.html' title='A feature that I would love to see in future IDEs...'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-5850685269468732602</id><published>2007-11-28T22:03:00.000-08:00</published><updated>2007-11-28T22:09:45.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thankgoditsover'/><category scheme='http://www.blogger.com/atom/ns#' term='dbc'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnet'/><title type='text'>LinFu.DesignByContract2 Released!</title><content type='html'>After nearly three weeks of churning away at &lt;a href="http://www.codeproject.com/cs/library/LinFuPart3.asp"&gt;Part V&lt;/a&gt; (not yet available on CodeProject at the time of this post) and making sure that everything works, I'm proud to say that LinFu.DesignByContract2 has been released to the project's &lt;a href="http://http://code.google.com/p/linfu/source"&gt;subversion repository&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;I practically froze all my other research projects until I could get this thing done. Now that it's finally complete, I can move over the rest of my projects from VS2005 to VS2008, and continue my work on IL instrumentation and writing my own version of Reflection.Emit.&lt;br /&gt;&lt;br /&gt;Finally, I can take a break!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-5850685269468732602?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/5850685269468732602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/11/linfudesignbycontract2-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5850685269468732602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/5850685269468732602'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/11/linfudesignbycontract2-released.html' title='LinFu.DesignByContract2 Released!'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-4184241733141721220</id><published>2007-11-11T16:10:00.000-08:00</published><updated>2007-11-11T16:41:03.460-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ohthehumanity'/><category scheme='http://www.blogger.com/atom/ns#' term='enoughisenough'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='sloppycode'/><category scheme='http://www.blogger.com/atom/ns#' term='cecil'/><title type='text'>Enough with Mono.Cecil.</title><content type='html'>After hitting several NullReferenceExceptions with Mono.Cecil's source code, enough is enough. I can't seem to make heads or tails of how to fix this problem, and frankly, I think it's pretty damn sloppy not to check for a simple null reference. Here's a chunk of the offending code:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photobucket.com" width="100%" target="_blank"&gt;&lt;img src="http://i16.photobucket.com/albums/b33/marttub/cecil1.png" border="0" alt="Photo Sharing and Video Hosting at Photobucket"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It would be OK if this happened only once; the problem is that I can see several sections of code where they make the same mistake over and over again. The number one thing that I hate is when other people write sloppy code and it leaves me no choice but to wait for them to fix it because the code is too complicated to fix on my own. Mono.Cecil has zero unit tests, so there's hardly any way to actually determine which part of the entire library actually works. And frankly, it really doesn't matter to me whether or not they're still in 'beta', or 'alpha', or whatever version--it still doesn't excuse the fact that no matter what version your program should be, these people should have the common sense (as well as the decency) to do some basic error checking!&lt;br /&gt;&lt;br /&gt;That's it. I'm tired of this shit. I'm writing my own library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-4184241733141721220?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/4184241733141721220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/11/enough-with-monocecil.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/4184241733141721220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/4184241733141721220'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/11/enough-with-monocecil.html' title='Enough with Mono.Cecil.'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7349901047715470998.post-3254758277853727243</id><published>2007-10-25T16:11:00.001-07:00</published><updated>2007-10-25T23:33:20.362-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clr'/><category scheme='http://www.blogger.com/atom/ns#' term='linfu'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamiclanguages'/><category scheme='http://www.blogger.com/atom/ns#' term='dotnet'/><category scheme='http://www.blogger.com/atom/ns#' term='csharp'/><title type='text'>Introducing LinFu, Part II: Adding Dynamic Language Features to Statically-Typed Languages in .NET (A Preview)</title><content type='html'>&lt;span style="font-family:verdana;"&gt;CodeProject is taking quite a while to publish a copy of Part II, so I've decided to publish a copy of it on this blog instead. You can download it from &lt;a href="http://marttub.orbitfiles.com/LinFuPart2.zip"&gt;this link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Its highlights include a few dynamic language features such as:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li style="font-family: verdana;"&gt;Late Binding&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:verdana;"&gt;Duck Typing&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:verdana;"&gt;Mixins&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:verdana;"&gt;Dynamically Generated Methods&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;It's a pretty hefty article, but if you're looking to make your statically-typed code a bit easier by using some of the dynamic language features I just mentioned, then this article was written just for developers like you.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7349901047715470998-3254758277853727243?l=plaureano.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://plaureano.blogspot.com/feeds/3254758277853727243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://plaureano.blogspot.com/2007/10/introducing-linfu-part-ii-adding.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3254758277853727243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7349901047715470998/posts/default/3254758277853727243'/><link rel='alternate' type='text/html' href='http://plaureano.blogspot.com/2007/10/introducing-linfu-part-ii-adding.html' title='Introducing LinFu, Part II: Adding Dynamic Language Features to Statically-Typed Languages in .NET (A Preview)'/><author><name>Philip Laureano</name><uri>http://www.blogger.com/profile/08456668588660909284</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
