<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Buu Nguyen's Blog</title>
	
	<link>http://www.buunguyen.net/blog</link>
	<description>Thoughts on Software Engineering</description>
	<lastBuildDate>Fri, 01 Jan 2010 03:10:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BuuNguyensBlog" /><feedburner:info uri="buunguyensblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>BuuNguyensBlog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Fasterflect vs. C# 4.0 Dynamic</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/SaQZlCLWfcw/fasterflect-vs-c-4-0-dynamic.html</link>
		<comments>http://www.buunguyen.net/blog/fasterflect-vs-c-4-0-dynamic.html#comments</comments>
		<pubDate>Thu, 31 Dec 2009 14:55:29 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[fasterflect]]></category>
		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=430</guid>
		<description><![CDATA[As .NET 4.0 final release will hit the market pretty soon, it&#8217;s worth discussing the value of Fasterflect in the face of C# 4.0&#8217;s dynamic keyword.  (If you aren&#8217;t familiar with C# 4.0 dynamic, you should read my article on C# 4.0 before continuing.)
To recall, Fasterflect was designed to address 2 key disadvantages of .NET [...]]]></description>
			<content:encoded><![CDATA[<p>As .NET 4.0 final release will hit the market pretty soon, it&#8217;s worth discussing the value of <a href="http://www.buunguyen.net/blog/net-reflection-made-fast-simple-fasterflect-1-1-release.html">Fasterflect</a> in the face of C# 4.0&#8217;s dynamic keyword.  (If you aren&#8217;t familiar with C# 4.0 dynamic, you should read <a href="http://www.codeproject.com/KB/cs/csharp_4_overview.aspx">my article on C# 4.0</a> before continuing.)</p>
<p>To recall, Fasterflect was designed to address 2 key disadvantages of .NET Reflection: ease of use and performance.  As seen in my article about C# 4.0, the dynamic keyword nicely addresses the easy of use with a resulting syntax looking even nicer than Fasterflect.  How about performance?</p>
<p>I improved the <a href="http://www.codeproject.com/KB/library/fasterflect_.aspx">benchmark application</a> of Fasterflect to add some benchmark code comparing between the performance of C# 4.0 dynamic and Fasterflect.  Here is result of method invocation benchmark.</p>
<p><img class="alignnone size-full wp-image-431" title="fasterflectbenchmark" src="http://www.buunguyen.net/blog/wp-content/uploads/2009/12/fasterflectbenchmark.png" alt="fasterflectbenchmark" width="384" height="143" /></p>
<p>While performing slower than Fasterflect&#8217;s cached API, C# dynamic performs much better than Fasterflect&#8217;s standard API.  (Not surprisingly, the C# dynamic binding doesn&#8217;t resort to the slow reflection mechanism internally.)</p>
<p>With this awareness in mind, together with the understanding about the features of C# dynamic and Fasterflect, let&#8217;s discuss about areas where Fasterflect shines even in the face of C# 4.0 dynamic:</p>
<ul>
<li>C# dynamic doesn&#8217;t handle invocations performed based on dynamic information (i.e. field name read from XML file).</li>
<li>C# dynamic does handle certain types of dynamic invocations, including static method invocation, static property invocation and constructor invocation.</li>
<li>C# dynamic doesn&#8217;t handle non-public members.  So you&#8217;ll receive exception if trying to, say, invoke a private method.</li>
<li>When performance is more critical than readability then the Fasterflect&#8217;s cached API might be favored over C# dynamic.</li>
</ul>
<p>Granted, there should be workarounds for the first 3 items.  For example, if you want to invoke static method dynamically with C# dynamic, you would have to workaround like the approach described in <a href="http://blogs.msdn.com/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx">this article</a>.  However, the approach uses reflection behind the scene so you would have the same performance issue to start with.</p>
<p>This doesn&#8217;t say that Fasterflect is better than C# dynamic though.  While both share a couple of features and maybe used interchangeably in some scenarios, they also have different problems of their own to address.  There are many things that you can do with C# dynamic that you couldn&#8217;t do with Fasterflect, e.g. implementing an interceptor to dynamically handle all method invocations (or missing methods) etc.  So, pick the right tool for your problem at hand.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Ffasterflect-vs-c-4-0-dynamic.html&amp;linkname=Fasterflect%20vs.%20C%23%204.0%20Dynamic"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=SaQZlCLWfcw:PZhx4tcpVLc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=SaQZlCLWfcw:PZhx4tcpVLc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=SaQZlCLWfcw:PZhx4tcpVLc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=SaQZlCLWfcw:PZhx4tcpVLc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=SaQZlCLWfcw:PZhx4tcpVLc:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/fasterflect-vs-c-4-0-dynamic.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/fasterflect-vs-c-4-0-dynamic.html</feedburner:origLink></item>
		<item>
		<title>Speaking at Barcamp Saigon 2009</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/jgN9ajZBEv4/speaking-at-barcamp-saigon-2009.html</link>
		<comments>http://www.buunguyen.net/blog/speaking-at-barcamp-saigon-2009.html#comments</comments>
		<pubDate>Wed, 16 Dec 2009 14:09:22 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[barcampsaigon]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[combres]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[fasterflect]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=414</guid>
		<description><![CDATA[I spoke at Barcamp Saigon 2009 last Sunday.  It was a fun event.  Met a number of interesting people and learned some new things from other sessions.  I talked about the two open-source libraries I developed, Fasterflect &#38; Combres.  Below are the slides I used for my presentations.
Fasterflect
View more presentations from [...]]]></description>
			<content:encoded><![CDATA[<p>I spoke at <a href="http://www.barcampsaigon.org/">Barcamp Saigon 2009</a> last Sunday.  It was a fun event.  Met a number of interesting people and learned some new things from other sessions.  I talked about the two open-source libraries I developed, <a href="http://www.buunguyen.net/blog/net-reflection-made-fast-simple-fasterflect-1-1-release.html">Fasterflect</a> &amp; <a href="http://www.buunguyen.net/blog/combres-webform-mvc-client-side-resource-combine-library.html">Combres</a>.  Below are the slides I used for my presentations.</p>
<div style="width:425px;text-align:left" id="__ss_2713206"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/buunguyen/fasterflect" title="Fasterflect">Fasterflect</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=fasterflect-091214031041-phpapp02&#038;rel=0&#038;stripped_title=fasterflect" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=fasterflect-091214031041-phpapp02&#038;rel=0&#038;stripped_title=fasterflect" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/buunguyen">Buu Nguyen</a>.</div>
</div>
<div style="width:425px;text-align:left" id="__ss_2713208"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/buunguyen/combres" title="Combres">Combres</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=combres-091214031306-phpapp02&#038;rel=0&#038;stripped_title=combres" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=combres-091214031306-phpapp02&#038;rel=0&#038;stripped_title=combres" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/buunguyen">Buu Nguyen</a>.</div>
</div>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fspeaking-at-barcamp-saigon-2009.html&amp;linkname=Speaking%20at%20Barcamp%20Saigon%202009"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=jgN9ajZBEv4:iVZ59z6qVjY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=jgN9ajZBEv4:iVZ59z6qVjY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=jgN9ajZBEv4:iVZ59z6qVjY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=jgN9ajZBEv4:iVZ59z6qVjY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=jgN9ajZBEv4:iVZ59z6qVjY:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/speaking-at-barcamp-saigon-2009.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/speaking-at-barcamp-saigon-2009.html</feedburner:origLink></item>
		<item>
		<title>.NET Reflection Made Fast &amp; Simple – Fasterflect 1.1 Release</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/YOj95rNdyu0/net-reflection-made-fast-simple-fasterflect-1-1-release.html</link>
		<comments>http://www.buunguyen.net/blog/net-reflection-made-fast-simple-fasterflect-1-1-release.html#comments</comments>
		<pubDate>Thu, 19 Nov 2009 13:48:35 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[dynamic-method]]></category>
		<category><![CDATA[emit]]></category>
		<category><![CDATA[fasterflect]]></category>
		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=398</guid>
		<description><![CDATA[I&#8217;m pleased to announce that version 1.1 of Fasterflect, the fast &#038; simple .NET reflection invocation library, is already released in CodePlex.  The download include Fasterflect binary, code documentation, benchmark application source, sample code, unit test source (95%+ coverage, can be used to learn about all usage aspect of Fasterflect).
For an introduction to Fasterflect, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce that version 1.1 of Fasterflect, the fast &#038; simple .NET reflection invocation library, is already released in <a href="http://fasterflect.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36129">CodePlex</a>.  The download include Fasterflect binary, code documentation, benchmark application source, sample code, unit test source (95%+ coverage, can be used to learn about all usage aspect of Fasterflect).</p>
<p>For an introduction to Fasterflect, including its design, APIs, and benchmark, please refer to <a href="http://www.codeproject.com/KB/library/fasterflect_.aspx">this Code Project article</a>.</p>
<p>Changes since version 1.0 beta (the one documented in the Code Project article) include:</p>
<ul>
<li>Support array types (construction, set element, get element)</li>
<li>Support structs </li>
<li>Support ref/out parameters</li>
<li>Support lookup by covariant parameter type</li>
<li>Inference of parameter types for non-null arguments</li>
<li>Several bug fixes</li>
</ul>
<p><strong>Sample Code</strong></p>
<pre class="brush:csharp">
class PersonClass
{
    private int id;
    private int milesTraveled;
    public int Id
    {
        get { return id; }
        set { id = value; }
    }
    public string Name { get; private set; }
    private static int InstanceCount;

    public PersonClass() : this(0) {}

    public PersonClass(int id) : this(id, string.Empty) { }

    public PersonClass(int id, string name)
    {
        Id = id;
        Name = name;
        InstanceCount++;
    }

    public char this[int index]
    {
        get { return Name[index]; }
    }

    private void Walk(int miles)
    {
        milesTraveled += miles;
    }

    private static void IncreaseInstanceCount()
    {
        InstanceCount++;
    }

    private static int GetInstanceCount()
    {
        return InstanceCount;
    }

    public static void Swap(ref int i, ref int j)
    {
        int tmp = i;
        i = j;
        j = tmp;
    }
}
</pre>
<pre class="brush:csharp">
struct PersonStruct
{
    private int id;
    private int milesTraveled;
    public int Id
    {
        get { return id; }
        set { id = value; }
    }
    public string Name { get; private set; }
    private static int InstanceCount;

    public PersonStruct(int id) : this(id, string.Empty) { }

    public PersonStruct(int id, string name) : this()
    {
        Id = id;
        Name = name;
        InstanceCount++;
    }

    public char this[int index]
    {
        get { return Name[index]; }
    }

    private void Walk(int miles)
    {
        milesTraveled += miles;
    }

    private static void IncreaseInstanceCount()
    {
        InstanceCount++;
    }

    private static int GetInstanceCount()
    {
        return InstanceCount;
    }

    public static void Swap(ref int i, ref int j)
    {
        int tmp = i;
        i = j;
        j = tmp;
    }
}
</pre>
<pre class="brush:csharp">
class Program
{
    static void Main()
    {
        // Load a type reflectively, just to look like real-life scenario
        var types = new[]
                        {
                            Assembly.GetExecutingAssembly().GetType(&quot;FasterflectSample.PersonClass&quot;),
                            Assembly.GetExecutingAssembly().GetType(&quot;FasterflectSample.PersonStruct&quot;)
                        };
        Array.ForEach(types, type =&gt;
                                 {
                                     ExecuteNormalApi(type);
                                     ExecuteCacheApi(type);
                                 });
    }

    private static void ExecuteNormalApi(Type type)
    {
        bool isStruct = type.IsValueType;

        // Person.InstanceCount should be 0 since no instance is created yet
        AssertTrue(type.GetField&lt;int&gt;(&quot;InstanceCount&quot;) == 0);

        // Invokes the no-arg constructor
        object obj = type.Construct();

        // Double-check if the constructor is invoked successfully or not
        AssertTrue(null != obj);

        // struct's no-arg constructor cannot be overriden, thus the following checking
        // is not applicable to struct type
        if (!isStruct)
        {
            // Now, Person.InstanceCount should be 1
            AssertTrue(1 == type.GetField&lt;int&gt;(&quot;InstanceCount&quot;));

            // What if we don't know the type of InstanceCount?
            // Just specify object as the type parameter
            AssertTrue(type.GetField&lt;object&gt;(&quot;InstanceCount&quot;) != null);
        }

        // We can bypass the constructor to change the value of Person.InstanceCount
        type.SetField(&quot;InstanceCount&quot;, 2);
        AssertTrue(2 == type.GetField&lt;int&gt;(&quot;InstanceCount&quot;));

        // Let's invoke Person.IncreaseCounter() static method to increase the counter
        // In fact, let's chain the calls to increase 2 times
        type.Invoke(&quot;IncreaseInstanceCount&quot;)
            .Invoke(&quot;IncreaseInstanceCount&quot;);
        AssertTrue(4 == type.GetField&lt;int&gt;(&quot;InstanceCount&quot;));

        // Now, let's retrieve Person.InstanceCount via the static method GetInstanceCount
        AssertTrue(4 == type.Invoke&lt;int&gt;(&quot;GetInstanceCount&quot;));

        // If we're not interested in the return (e.g. only in the side effect),
        // we don't have to specify the type parameter (and can chain the result).
        AssertTrue(4 == type.Invoke(&quot;GetInstanceCount&quot;)
                            .Invoke(&quot;GetInstanceCount&quot;)
                            .Invoke&lt;int&gt;(&quot;GetInstanceCount&quot;));

        // Invoke method receiving ref/out params, we need to put arguments in an array
        var arguments = new object[] { 1, 2 };
        type.Invoke(&quot;Swap&quot;,
            // Parameter types must be set to the appropriate ref type
            new[] { typeof(int).MakeByRefType(), typeof(int).MakeByRefType() },
            arguments);
        AssertTrue(2 == (int)arguments[0]);
        AssertTrue(1 == (int)arguments[1]);

        // Now, invoke the 2-arg constructor.  We don't even have to specify parameter types
        // if we know that the arguments are not null (Fasterflect will internally retrieve type info).
        obj = type.Construct(1, &quot;Doe&quot;);

        // Due to struct type's pass-by-value nature, in order for struct to be used
        // properly with Fasterflect, you need to convert it into a holder (wrapper) first.
        // The call below does nothing if obj is reference type so when unsure, just call it.
        obj = obj.CreateHolderIfValueType();

        // id and name should have been set properly
        AssertTrue(1 == obj.GetField&lt;int&gt;(&quot;id&quot;));
        AssertTrue(&quot;Doe&quot; == obj.GetProperty&lt;string&gt;(&quot;Name&quot;));

        // Let's use the indexer to retrieve the character at index 1
        AssertTrue('o' == obj.GetIndexer&lt;char&gt;(1));

        // If there's null argument, or when we're unsure whether there's a null argument
        // we must explicitly specify the param type array
        obj = type.Construct(new[] { typeof(int), typeof(string) }, new object[] { 1, null })
            .CreateHolderIfValueType();

        // id and name should have been set properly
        AssertTrue(1 == obj.GetField&lt;int&gt;(&quot;id&quot;));
        AssertTrue(null == obj.GetProperty&lt;string&gt;(&quot;Name&quot;));

        // Now, modify the id
        obj.SetField(&quot;id&quot;, 2);
        AssertTrue(2 == obj.GetField&lt;int&gt;(&quot;id&quot;));
        AssertTrue(2 == obj.GetProperty&lt;int&gt;(&quot;Id&quot;));

        // We can chain calls
        obj.SetField(&quot;id&quot;, 3).SetProperty(&quot;Name&quot;, &quot;Buu&quot;);
        AssertTrue(3 == obj.GetProperty&lt;int&gt;(&quot;Id&quot;));
        AssertTrue(&quot;Buu&quot; == obj.GetProperty&lt;string&gt;(&quot;Name&quot;));

        // How about modifying both properties at the same time using an anonymous sample
        obj.SetProperties(new {
                                  Id = 4,
                                  Name = &quot;Nguyen&quot;
                              });
        AssertTrue(4 == obj.GetProperty&lt;int&gt;(&quot;Id&quot;));
        AssertTrue(&quot;Nguyen&quot; == obj.GetProperty&lt;string&gt;(&quot;Name&quot;));

        // Let's have the folk walk 6 miles (and try chaining again)
        obj.Invoke(&quot;Walk&quot;, 1).Invoke(&quot;Walk&quot;, 2).Invoke(&quot;Walk&quot;, 3);

        // Double-check the current value of the milesTravelled field
        AssertTrue(6 == obj.GetField&lt;int&gt;(&quot;milesTraveled&quot;));

        // Construct an array of 10 elements for current type
        var arr = type.MakeArrayType().Construct(10);

        // Get &amp; set element of array
        obj = type.Construct();
        arr.SetElement(4, obj).SetElement(9, obj);

        if (isStruct) // struct, won't have same reference
        {
            AssertTrue(obj.Equals(arr.GetElement&lt;object&gt;(4)));
            AssertTrue(obj.Equals(arr.GetElement&lt;object&gt;(9)));
        }
        else
        {
            AssertTrue(obj == arr.GetElement&lt;object&gt;(4));
            AssertTrue(obj == arr.GetElement&lt;object&gt;(9));
        }

        // Remember, struct array doesn't have null element
        // (instead always initialized to default struct)
        if (!isStruct)
        {
            AssertTrue(null == arr.GetElement&lt;object&gt;(0));
        }
    }

    private static void ExecuteCacheApi(Type type)
    {
        var range = Enumerable.Range(0, 10).ToList();

        // Let's cache the getter for InstanceCount
        StaticAttributeGetter count = type.DelegateForGetStaticField(&quot;InstanceCount&quot;);

        // Now cache the 2-arg constructor of Person and playaround with the delegate returned
        int currentInstanceCount = (int)count();
        ConstructorInvoker ctor = type.DelegateForConstruct(new[] { typeof(int), typeof(string) });
        range.ForEach(i =&gt;
        {
            object obj = ctor(i, &quot;_&quot; + i).CreateHolderIfValueType();
            AssertTrue(++currentInstanceCount == (int)count());
            AssertTrue(i == obj.GetField&lt;int&gt;(&quot;id&quot;));
            AssertTrue(&quot;_&quot; + i == obj.GetProperty&lt;string&gt;(&quot;Name&quot;));
        });

        // Whatever thing we can do with the normal API, we can do with the cache API.
        // For example:
        AttributeSetter nameSetter = type.DelegateForSetProperty(&quot;Name&quot;);
        AttributeGetter nameGetter = type.DelegateForGetProperty(&quot;Name&quot;);

        object person = ctor(1, &quot;Buu&quot;).CreateHolderIfValueType();
        AssertTrue(&quot;Buu&quot; == nameGetter(person));
        nameSetter(person, &quot;Doe&quot;);
        AssertTrue(&quot;Doe&quot; == nameGetter(person));

        // Another example
        person = type.Construct().CreateHolderIfValueType();
        MethodInvoker walk = type.DelegateForInvoke(&quot;Walk&quot;, new[] { typeof(int) });
        range.ForEach(i =&gt; walk(person, i));
        AssertTrue(range.Sum() == person.GetField&lt;int&gt;(&quot;milesTraveled&quot;));
    }

    public static void AssertTrue(bool expression)
    {
        if (!expression)
            throw new Exception(&quot;Not true&quot;);
        Console.WriteLine(&quot;Ok!&quot;);
    }
}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fnet-reflection-made-fast-simple-fasterflect-1-1-release.html&amp;linkname=.NET%20Reflection%20Made%20Fast%20%26%23038%3B%20Simple%20%26%238211%3B%20Fasterflect%201.1%20Release"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=YOj95rNdyu0:YUZIwjTuQo0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=YOj95rNdyu0:YUZIwjTuQo0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=YOj95rNdyu0:YUZIwjTuQo0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=YOj95rNdyu0:YUZIwjTuQo0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=YOj95rNdyu0:YUZIwjTuQo0:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/net-reflection-made-fast-simple-fasterflect-1-1-release.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/net-reflection-made-fast-simple-fasterflect-1-1-release.html</feedburner:origLink></item>
		<item>
		<title>Combres – WebForm &amp; MVC Client-side Resource Combine Library</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/VZ4v2JQI5zM/combres-webform-mvc-client-side-resource-combine-library.html</link>
		<comments>http://www.buunguyen.net/blog/combres-webform-mvc-client-side-resource-combine-library.html#comments</comments>
		<pubDate>Wed, 04 Nov 2009 13:56:23 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[combres]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=392</guid>
		<description><![CDATA[Combres (i.e. Combine-Resources), is a very easy-to-use library which can be used to automate many steps that you would have to do yourself when applying many performance optimization techniques in your MVC and Web Form ASP.NET applications.  This library is formerly known as ASP.NET MVC Client-side Resource Combine Library until I decided to retire [...]]]></description>
			<content:encoded><![CDATA[<p>Combres (i.e. Combine-Resources), is a very easy-to-use library which can be used to automate many steps that you would have to do yourself when applying many performance optimization techniques in your MVC and Web Form ASP.NET applications.  This library is formerly known as ASP.NET MVC Client-side Resource Combine Library until I decided to retire that boring and lengthy name.  Combres is also a major upgraded over the previous version.  In a nutshell, the following features are supported by Combres:</p>
<ul>
<li>Organize resource files, including JavaScript and CSS, into separate resource sets, each may share the same or use different configuration settings.
<ul>
<li>ConfigConfiguration settings are specified in an XML file which is monitored by Combres so that changes get noticed and applied immediately.</li>
<li>Resource files can be static files in the web server, dynamically generated files, or remote files from external servers or web applications.</li>
</ul>
</li>
<li>Allow files in resource sets to be combined, minified, and gzipped before sending to browser. All is done using 1 single HTTP request per resource set. (Refer to Yslow&#8217;s performance rules #1, #4 and #10 to know why this is useful.)
<ul>
<li>The minification part is performed by the great YUI Compressor library.</li>
</ul>
</li>
<li>Generate proper ETag and Expires/Cache-Control headers for every response as well as support server-side caching. (Refer to Yslow&#8217;s performance rules #3 and #13 to know why this is useful.)</li>
<li>Integrated with ASP.NET routing engine and thus work equally well for both ASP.NET MVC and ASP.NET WebForm applications.</li>
<li>Support Debugging mode, which won&#8217;t cache or minify contents at all to facilitate debugging.</li>
<li>Extensibility via the filtering architecture. Anyone can easily add more functionality to the Combres engine by writing a custom filter. There are 2 built-in filters in the 1.0 beta release, which I will describe in this article.</li>
</ul>
<p>I wrote about how to use and enhance this library in <a href="http://www.codeproject.com/KB/aspnet/combres.aspx">this Code Project article</a>.</p>
<p>You can also get the binary, source code and sample from these links:</p>
<ul>
<li><a href="http://combres.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35200#DownloadId=90101">Download Combres Binary</a></li>
<li><a href="http://combres.codeplex.com/SourceControl/changeset/view/30362#">Download Combres Source</a></li>
<li><a href="http://combres.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35200#DownloadId=90102">Download Samples</a></li>
</ul>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fcombres-webform-mvc-client-side-resource-combine-library.html&amp;linkname=Combres%20%26%238211%3B%20WebForm%20%26%23038%3B%20MVC%20Client-side%20Resource%20Combine%20Library"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=VZ4v2JQI5zM:UuUJv-MsloA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=VZ4v2JQI5zM:UuUJv-MsloA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=VZ4v2JQI5zM:UuUJv-MsloA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=VZ4v2JQI5zM:UuUJv-MsloA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=VZ4v2JQI5zM:UuUJv-MsloA:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/combres-webform-mvc-client-side-resource-combine-library.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/combres-webform-mvc-client-side-resource-combine-library.html</feedburner:origLink></item>
		<item>
		<title>Fasterflect – a fast and simple API for Reflection invocation</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/dSB7GVlrPMc/fasterflect-a-fast-and-simple-api-for-reflection-invocation.html</link>
		<comments>http://www.buunguyen.net/blog/fasterflect-a-fast-and-simple-api-for-reflection-invocation.html#comments</comments>
		<pubDate>Mon, 10 Aug 2009 06:21:09 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[dynamic-method]]></category>
		<category><![CDATA[emit]]></category>
		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=380</guid>
		<description><![CDATA[If you think the built-in Reflection API in the .NET framework is too verbose for many circumstances and has poor performance, you are not alone. I think that too. And yet, being able to write reflective code is an inevitable (technical) requirement in most of the applications I develop. This is why I have built [...]]]></description>
			<content:encoded><![CDATA[<p>If you think the built-in Reflection API in the .NET framework is too verbose for many circumstances and has poor performance, you are not alone. I think that too. And yet, being able to write reflective code is an inevitable (technical) requirement in most of the applications I develop. This is why I have built Fasterflect (read either &#8220;Faster-flect&#8221; or &#8220;Fast-reflect&#8221;) as an alternative API to the .NET Reflection functionality.</p>
<p>The goal of this library is to make Reflection calls as straightforward as possible while offering better performance than normal Reflection calls. In this article, I&#8217;ll describe the approach chosen to build Fasterflect, its APIs, and measure its performance via some benchmarks.</p>
<p>You can refer to <a href="http://www.codeproject.com/KB/library/fasterflect_.aspx">this Code Project page</a> for the guide to the library.  For latest development code &#038; binary, refer to <a href="http://fasterflect.codeplex.com/">the project page in CodePlex</a>.</p>
<p><b>Updated 8/19/2009:</b> Version 1.0 is released and can be downloaded from the <a href="http://fasterflect.codeplex.com/">CodePlex project page</a>.  This release supports ref/out parameters for methods/constructors/indexers and structs.  Implementing support for struct has been quite challenging (and thus interesting) due to its data-copy parameter passing semantic and my design goal of sharing the API for both structs &#038; classes (instead of creating a bunch of overloads for structs).</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Ffasterflect-a-fast-and-simple-api-for-reflection-invocation.html&amp;linkname=Fasterflect%20%26%238211%3B%20a%20fast%20and%20simple%20API%20for%20Reflection%20invocation"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=dSB7GVlrPMc:zEq0qYaAlOs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=dSB7GVlrPMc:zEq0qYaAlOs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=dSB7GVlrPMc:zEq0qYaAlOs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=dSB7GVlrPMc:zEq0qYaAlOs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=dSB7GVlrPMc:zEq0qYaAlOs:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/fasterflect-a-fast-and-simple-api-for-reflection-invocation.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/fasterflect-a-fast-and-simple-api-for-reflection-invocation.html</feedburner:origLink></item>
		<item>
		<title>ASP.NET MVC Client-side Resource Combine</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/_z9lY7Sg5A0/aspnet-mvc-client-side-resource-combine.html</link>
		<comments>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html#comments</comments>
		<pubDate>Fri, 26 Jun 2009 07:05:29 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=355</guid>
		<description><![CDATA[ASP.NET MVC Client-side Resource Combine is another spin-off library from one of my current development projects.  (The other is ASP.NET MVC Validation Library.)  While the name is &#8220;resource combine&#8221;, this library actually does more than just combining client side resources including JavaScript and CSS.  It allows you to organize resources into groups [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aspmvccombine.codeplex.com/">ASP.NET MVC Client-side Resource Combine</a> is another spin-off library from one of my current development projects.  (The other is <a href="http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html">ASP.NET MVC Validation Library</a>.)  While the name is &#8220;resource combine&#8221;, this library actually does more than just combining client side resources including JavaScript and CSS.  It allows you to organize resources into groups which will be combined, minified, compressed, and cached (at both client and server sides) together.  While the library comes bundled with some routing and link utility to help developers easily integrate it into their ASP.NET MVC applications, there&#8217;s no reason why the library cannot be used with ASP.NET WebForms applications.</p>
<p>Refer to the <a href="http://aspmvccombine.codeplex.com/">project CodePlex page</a> for detailed usage and binary/code download.  The library uses the great <a href="http://yuicompressor.codeplex.com/">YUI Compressor</a> library for the minification part.</p>
<p>Hopes it helps!</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Faspnet-mvc-client-side-resource-combine.html&amp;linkname=ASP.NET%20MVC%20Client-side%20Resource%20Combine"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=_z9lY7Sg5A0:a1V_eMzEh_Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=_z9lY7Sg5A0:a1V_eMzEh_Y:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html</feedburner:origLink></item>
		<item>
		<title>Lost of posts &amp; comments from 1/9/2009 to June/2009</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/FtsuC5tfjQE/lost-of-posts-comments-from-192009-to-june2009.html</link>
		<comments>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html#comments</comments>
		<pubDate>Fri, 26 Jun 2009 06:57:26 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[experience]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=372</guid>
		<description><![CDATA[Upon writing a new blog post today, I recognized an shocking truth: the provider hosting my blog during their database migration had somehow cleaned up all of my blog&#8217;s posts and comments dated after 1/8/2009.  Since I trusted my provider in their infrastructure, I did not do the backup job well myself so I [...]]]></description>
			<content:encoded><![CDATA[<p>Upon writing a new blog post today, I recognized an shocking truth: the provider hosting my blog during their database migration had somehow cleaned up all of my blog&#8217;s posts and comments dated after 1/8/2009.  Since I trusted my provider in their infrastructure, I did not do the backup job well myself so I did not have anything to repopulate the database.</p>
<p>Luckily, Google&#8217;s cache made it possible for me to retrieve the text and posted them again with an adjusted timestamp.  As for the comments, since there were many of them and yet not all of them could be found in Google&#8217;s cache, I had to leave them for now.  Therefore, you won&#8217;t see any comments dated from 1/9/2009 to around June 2009 (when the migration occurred).  My sincere apologies to those comments are lost due to this incidence.  I myself feel very very bad about it.  I will work with the host provider in a last attempt to find way to recover the comments.  If that doesn&#8217;t turn out right, I will find a new provider.  And I will surely backup my blog frequently in the future.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Flost-of-posts-comments-from-192009-to-june2009.html&amp;linkname=Lost%20of%20posts%20%26amp%3B%20comments%20from%201%2F9%2F2009%20to%20June%2F2009"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=FtsuC5tfjQE:FunCFn1AOOk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=FtsuC5tfjQE:FunCFn1AOOk:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html</feedburner:origLink></item>
		<item>
		<title>Junior developers beware, SOLID principles and design patterns are indeed useful for you</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/mIy5wMQX6UY/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html</link>
		<comments>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html#comments</comments>
		<pubDate>Fri, 13 Feb 2009 06:40:47 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career advices]]></category>
		<category><![CDATA[Self Improvement]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=368</guid>
		<description><![CDATA[I have several times disagreed with Jeff.  They are just rare occasions though, given the amount of blog posts he wrote and I read (and agreed with).  However, given his popularity as a blogger, any misleading advice may be highly destructive to junior software developers who may turn to his blog for advices. [...]]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://www.buunguyen.net/blog/jeff-atwood-on-design-patterns.html">several</a> <a href="http://www.buunguyen.net/blog/the-impassionate-and-nnpps-are-not-that-destructive.html">times</a> disagreed with Jeff.  They are just rare occasions though, given the amount of blog posts he wrote and I read (and agreed with).  However, given his popularity as a blogger, any misleading advice may be highly destructive to junior software developers who may turn to his blog for advices.  This time around, <a href="http://www.codinghorror.com/blog/archives/001225.html">Jeff bashes guidelines, rules, and checklist</a> with <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">SOLID principles</a> being one of the targets.</p>
<p>Now, young developers, before you start throwing away all the books about design patterns, agile, OO principles etc., let me tell you one thing: if Jeff Atwood is a better developer at all today, it&#8217;s because he has learned from the rules preached by more knowledgeable people.  Don&#8217;t believe?  Read <a href="http://www.codinghorror.com/blog/archives/000021.html">this</a>.  There you go, Jeff Atwood as a fan of <a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_sim_b_3">Code Complete</a>, a 900-page book full of coding rules, was so much interested in the book that he even named his blog after one of the book&#8217;s symbol.  He just seems to forget about where he came from when he wrote:</p>
<blockquote><p>While I do believe every software development team should endeavor to follow the instructions on the paint can, there&#8217;s a limit to what you can fit on a paint can. It&#8217;s the most basic, most critical information you need to proceed and not make a giant mess of the process. As brief as the instructions on a paint can are, they do represent the upper limit of what most people will realistically read, comprehend, and derive immediate benefit from. </p>
</blockquote>
<p>It&#8217;s normal for a very experienced developer to rely mostly on his judgment instead of a set of rules and principles to do thing.  But it&#8217;s just uncool for such an experienced developer to advise the newbies to do the same thing, i.e. they&#8217;d better use their judgment first before resorting to the distilled and valuable knowledge taught by others.  </p>
<blockquote><p>&#8230;I&#8217;ve found less and less use for rules in my career. Not because I&#8217;m a self-made genius who plays by my own rules, mind you, but because I value the skills, experience, and judgment of my team far more than any static set of rules&#8230;  Rules, guidelines, and principles are gems of distilled experience that should be studied and respected. But they&#8217;re never a substute for thinking critically about your work.</p>
</blockquote>
<p>The thing is people are not born making good judgment.  And one of the best ways to sharpen one&#8217;s judgment is to learn from the knowledge of those people who have made good judgment.  Only after one has practiced these teachings long enough, making a lot of right and wrong decisions based on these teachings, one will for the first time, really understand about them and don&#8217;t have to think about them any longer as they have become part of one&#8217;s instinct.  That should be the thing experienced developers teach junior developers, not this:</p>
<blockquote><p>The types of developers who could benefit from SOLID a) aren&#8217;t thoughtful enough about their work to care and b) won&#8217;t read much of anything</p>
</blockquote>
<p>Don&#8217;t get me wrong, I respect many of Jeff&#8217;s opinions, but I think he should feel more responsible for his influence on those developers who are new to the industry and seek for advices from his writings.  Obviously no one man is perfect and Jeff, like any other, doesn&#8217;t necessarily always have great things to say.  But at least he should acknowledge that he&#8217;s wrong when he&#8217;s wrong.  </p>
<p><strong>Appendum 2/14</strong><br />
On the contrary to what I think Jeff Atwood should do in the previous paragraph given the large amount of thoughtful comments from many of his readers, he seems to dig himself deeper into the hole with his <a href="http://www.codinghorror.com/blog/archives/000856.html">follow-up post</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fjunior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html&amp;linkname=Junior%20developers%20beware%2C%20SOLID%20principles%20and%20design%20patterns%20are%20indeed%20useful%20for%20you"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=mIy5wMQX6UY:-TSCJaejMh4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=mIy5wMQX6UY:-TSCJaejMh4:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html</feedburner:origLink></item>
		<item>
		<title>ASP.NET MVC Validation Library</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/Hqpj3ccce2I/aspnet-mvc-validation-library.html</link>
		<comments>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html#comments</comments>
		<pubDate>Tue, 10 Feb 2009 06:32:18 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[codeplex]]></category>
		<category><![CDATA[enterprise library]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=364</guid>
		<description><![CDATA[Inspired by the work of Emad Ibrahim, I set out to develop a validation library for ASP.NET MVC.  Besides trying to meet the same objectives as Emad Ibrahim&#8217;s library, i.e. model-based validation, integration with the jQuery validation plugin, and little or no duplication between client-side and server-side validation, these are the differences of my [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://www.emadibrahim.com/2008/09/08/client-server-side-validation-in-aspnet-mvc/">the work</a> of Emad Ibrahim, I set out to develop a validation library for ASP.NET MVC.  Besides trying to meet the same objectives as Emad Ibrahim&#8217;s library, i.e. model-based validation, integration with the <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery validation plugin</a>, and little or no duplication between client-side and server-side validation, these are the differences of my library:</p>
<ul>
<li>Built for <a href="Validation Application Block?PHPSESSID=3c28d1ec5adc35404e534c68747bf06b">MS Validation Application Block</a>.  (Emad Ibrahim&#8217;s library targets <a href="http://www.castleproject.org/">Castle</a>&#8217;s validation framework.  Check out <a href="http://www.emadibrahim.com/2008/09/08/client-server-side-validation-in-aspnet-mvc">his library</a> if you need this feature.)</li>
<li>Allow users to specify the properties to be included in a server-side validation.  This is useful in situation in which you use part of the model in some pages (e.g. Change Password page only uses the <code>Password</code> field of the <code>User </code>entity).</li>
<li>Allow users to tell the client-side code generator to generate script to ignore missing DOM elements.  This feature goes nicely with the above feature.  The generator could have been implemented to receive a list of properties to generate client script for but I have not made up my mind yet whether this is a better approach or not.</li>
<li>Allow users to specify whether they want the validation initialization code to be generated or not.  This is particular useful if you want to customize the validation initialization code differently for different pages.</li>
</ul>
<p><strong>How does it work?</strong><br />
The idea of the library is that one should be able to decorate an entity object with some validation attributes and then have that entity validated at both the server-side and client-side with the minimum amount of code.  Let&#8217;s say you have a <code>User</code> entity in your application, you can annotate it as follows:</p>
<pre class="brush:csharp">
public class User
{
     [NotNullOrEmptyValidator(MessageTemplate = "Name is required")]
     [StringLengthValidator(6, 20, MessageTemplate = "Name must be between {3} and {5}")]
     public string Name { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Email is required")]
     [EmailValidator(MessageTemplate = "Invalid email address")]
     public string Email { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Location is required")]
     public string Location { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Password is required")]
     [StringLengthValidator(6, 50, MessageTemplate = "Password must be between {3} and {5}")]
     public string Password { get; set; }
}
</pre>
<p>Now, whenever this entity is populated with form posted values, you can perform server-side validation by invoking the <code>Validate()</code> extension method on the entity.  Let&#8217;s do that in the action method.</p>
<pre class="brush:csharp">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditUser([Bind(Prefix=&quot;&quot;)]User user)
{
     try
     {
          user.Validate&lt;User&gt;();
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}
</pre>
<p>The above code will perform validation on the entity given its validation attributes.  If there&#8217;s any validation error, an <code>EntityValidationException </code>object is thrown and you can use it the populate the model state with error messages.  The method <code>PopulateWithErrors </code>is another extension method provided by the library.</p>
<p>If you want to limit the properties to be validated (e.g. in a password change scenario), you can pass an array of property names into the <code>Validate()</code> method.</p>
<pre class="brush:csharp">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangePassword([Bind(Prefix=&quot;&quot;)]User user)
{
     try
     {
          // Only validate the password property
          user.Validate&lt;User&gt;(new[] {&quot;password&quot;});
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}
</pre>
<p>I could have added a custom model binder to the library so that validation happens at the model binding phase but I think that&#8217;s not a flexible approach since in many cases we would want to perform validation in the service layer instead so that the validation takes place consistently for any client of the service.</p>
<p>Let&#8217;s see the result of the server-side validation:<br />
<img src="http://www.buunguyen.net/blog/wp-content/uploads/2009/02/server-side-validation.png" alt="" title="Server-side validation result" width="322" height="375" class="size-full wp-image-391" /></p>
<p>Okay, let&#8217;s move to client-side validation.  The trick behind the client-side validation is that the view will invokes the <code>HtmlHelper</code>&#8217;s <code>ClientSideValidation()</code> extension method which will retrieve all validation attributes of the specified entity type (e.g. <code>User</code>) and generate equivalent client-side validation script for them.  </p>
<p>Currently, while you can apply as many validation attributes to an entity as you like and the server-side validation will work perfectly fine, only a couple of validation rules are supported by the client-side code generator, namely required field validation, string length validation, and email validation.  These3 rules are sufficient for my current need and I will add more on a needed basis (or you can download the code and implement more rules yourself.) </p>
<p>There are a couple of overloads of the <code>ClientSideValidation() </code>method:</p>
<pre class="brush:csharp">
// Generates validation script for the User type
Html.ClientSideValidation&lt;User&gt;();

// Generates validation script for the User type, including the code to initialize form validation
Html.ClientSideValidation&lt;User&gt;(string formName);

// Generates validation script for the User type and adds necessary code to avoid JavaScript error if one or
// more properties in the User type do not match with any DOM element.
Html.ClientSideValidation&lt;User&gt;(bool ignoreMissingElements);

// See the above 2 overloads
Html.ClientSideValidation&lt;User&gt;(string formName, bool ignoreMissingElements);
</pre>
<p>For example, the generated code for an invocation of the second overload will result in the following code:</p>
<pre class="brush:csharp">
&lt;script language=&quot;JavaScript&quot;&gt;&lt;!--
$().ready(function() {

$(&quot;#edit-user-form&quot;).validate();
$(&quot;#name&quot;).rules(&quot;add&quot;, {
	minlength : &quot;6&quot;, maxlength : &quot;20&quot;,
	required : true,
	messages: {
		minlength : &quot;Name must be between 6 and 20&quot;, maxlength : &quot;Name must be between 6 and 20&quot;,
		required : &quot;Name is required&quot;

	}
});

$(&quot;#email&quot;).rules(&quot;add&quot;, {
	required : true,
	email : true,
	messages: {
		required : &quot;Email is required&quot;,
		email : &quot;Invalid email address&quot;
	}
});

$(&quot;#location&quot;).rules(&quot;add&quot;, {
	required : true,
	messages: {
		required : &quot;Location is required&quot;

	}
});

$(&quot;#password&quot;).rules(&quot;add&quot;, {
	minlength : &quot;6&quot;, maxlength : &quot;50&quot;,
	required : true,
	messages: {
		minlength : &quot;Password must be between 6 and 50&quot;, maxlength : &quot;Password must be between 6 and 50&quot;,
		required : &quot;Password is required&quot;
	}
});

});
--&gt;&lt;/script&gt;
</pre>
<p>That&#8217;s it, you don&#8217;t need to write a single line of JavaScript to have this nice client-side validation:<br />
<img alt="" src="http://www.buunguyen.net/blog/wp-content/uploads/2009/02/client-side-validation.png" title="Client-side validation result" class="size-full wp-image-391" width="452" height="274" /></p>
<p><strong>How can I download and use it?</strong><br />
The library is hosted at <a href="http://www.codeplex.com/aspmvcvalidation">CodePlex</a>.  I have built it with ASP.NET MVC Beta, Enterprise Library 4.1, jQuery 1.2, and jQuery validation plug-in 1.5.  You might need to make a couple of changes if you want it to work with a different version of those libraries.  Any bug, please post on the project page instead of posting here.  Thanks &#038; hope you&#8217;ll find the library useful.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Faspnet-mvc-validation-library.html&amp;linkname=ASP.NET%20MVC%20Validation%20Library"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Hqpj3ccce2I:-0QahSOft8I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Hqpj3ccce2I:-0QahSOft8I:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html</feedburner:origLink></item>
		<item>
		<title>Common developers CV’s mistakes</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/Va1hu42pOXI/common-developers-cvs-mistakes.html</link>
		<comments>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html#comments</comments>
		<pubDate>Wed, 21 Jan 2009 06:28:49 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[hr]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[recruitment]]></category>
		<category><![CDATA[Self Improvement]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=357</guid>
		<description><![CDATA[Being responsible for hiring developers in almost every position I landed, I&#8217;ve screened probably a few hundreds of developers CVs through out my career.  Following is the list of mistakes I often found in CVs.

First and most common mistakes: the CV lists too many skills. In fact, I&#8217;ve seen many CVs with roughly a [...]]]></description>
			<content:encoded><![CDATA[<p>Being responsible for hiring developers in almost every position I landed, I&#8217;ve screened probably a few hundreds of developers CVs through out my career.  Following is the list of mistakes I often found in CVs.</p>
<ul>
<li><strong>First and most common mistakes: the CV lists too many skills.</strong> In fact, I&#8217;ve seen many CVs with roughly a dozen lines mentioning about many dozens of technologies and tools. In many cases as the on-site interviews revealed, these developers just possessed superficial or absolutely no knowledge about the things they listed.  One can only go so far (to the on-site interview) being untruthful.  On the other hand, even if these developers really know about these things, among the too many things they list, I can hardly find the ones that should really stand out (i.e. the things that the candidates have expertise in.)  Now, there are those of you who really have extensive set of skills under your belt and want to list them all, it&#8217;s still better if you can highlight the top skills that you master so that they can stand out from the rest. Most of the time, employers don&#8217;t care about the skills you are not really good at. Think about it, would I hire a top .NET developer to write Java code just because the guy happens to know a bit about Java?  </li>
<p></p>
<li><strong>Some candidates describe what they were supposed to do instead of what they actually did in their previous positions.</strong> If one implemented the security module of a software using Spring Security or used Struts 2.0 to implement a web module of another software then I would want to know about that. On the other hand, I don&#8217;t want to read a some general job description stating the obvious and of little interest (to me) such as &#8220;designed and implemented the application&#8221;, &#8220;worked with QA to resolve defects&#8221;, and &#8220;participated in code review&#8221; etc.  (Guess what, if you&#8217;re not doing these things, you are not developers.) On the other hand, some candidates went so far quoting text from the job description while they have not actually carried out such responsibilities and that has resulted in quite a couple of embarrassing on-site interviews. Be very specific about the things that you did is the key to avoid this mistake.</li>
<p></p>
<li><strong>Mention too much about the clients and products. </strong>As a matter of fact, I&#8217;ve seen some CVs in which every project is accompanied with a lengthy paragraph describing the product and its client. Much of this information is pulled out of the marketing information provided in the client&#8217;s or product&#8217;s website. Keep this in mind: most employers don&#8217;t care about the vision of your client organization and the greatness of the product. For the software that you built, only 2 things should be mentioned in the CV: what problem the software solves and what technologies it is built with.  Anything other than that is noise and should go away. For the client, the name and a link to their website are more than enough. For the really rare case that I want to learn more about the client, I will find more information through the provided link (or Google, for heaven&#8217;s sake).</li>
<p></p>
<li><strong>Some CVs mention too trivial projects.</strong> Don&#8217;t get me wrong, it&#8217;s good to demonstrate how much passionate you are about this software engineering by listing things like, say, personal projects but there&#8217;s no point mentioning some trivial toy or university projects in your CVs. Think about it, how much value the employer gains knowing that a developer can code a Tic Tac Toe game or a shopping cart? Absolutely nothing unless you expect us to say to ourselves &#8220;Look, that guy is really cool &#8211; he can code Tic Tac Toe.&#8221;  Save the space for more valuable things instead. If there&#8217;s no such thing, better save us some reading time by removing them from the CV.</li>
<p></p>
<li><strong>Spelling and grammar mistakes in CVs. </strong> I am constantly surprised that many developers don&#8217;t even care to do a quick check to make sure no grammatical and spelling mistakes in their CVs.  After all, it only takes a few minutes for this check to be done with any word processing software.  Without doing this, one risks leaving a bad impression to the recruiter; the impression that the author of this CV is either lazy, doesn&#8217;t care about getting the job, about doing the right things, or about going the last mile to get the work done.  That might be a harsh conclusion one can come up with given just a few spelling mistakes, but given the sheer amount of CVs recruiters have to screen for any particular position, they are not supposed to be very patient and tolerant of poorly written ones. </li>
<p></p>
<li><strong>A bonus tip: don&#8217;t be afraid to list your certifications if you have any. </strong> This is actually not a common mistake, but since there is a rising number of people who suggest that developers should not include certifications in their CVs, I think it&#8217;s worth setting an alarm.  Anyone who have under their belt a few certifications know that it&#8217;s not the papers themselves that have a lot of value but the actual studying process that one usually gets through to get those papers is valuable. Plus, if one spends the time that would otherwise be spent on vacation or gaming to study and achieve some certifications relevant to her work, it means that she cares, if is not passionate, about her job. And that is never a bad thing. Finally, with all things being equal, some companies would prefer to hire developers with one or more certifications than others because that would help with the partnership process with vendors like, say, Microsoft (like it or not, there are obvious benefits to become partner of the big vendors).</li>
</ul>
<p>That&#8217;s it, the top CV mistakes. Am I missing anything?</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fcommon-developers-cvs-mistakes.html&amp;linkname=Common%20developers%20CV%E2%80%99s%20mistakes"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Va1hu42pOXI:PZrbMt3euu4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Va1hu42pOXI:PZrbMt3euu4:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html</feedburner:origLink></item>
	</channel>
</rss>
