Paint War is released!!

December 22nd, 2011 Buu Nguyen 2 comments

This is the release month! After qTrace, another product I spent much mind and heart on for many months has just been released: Paint War, the super fun and addicted (shamelessly biased!) iPad game.  Visit Paint War’s website or iTunes App Store to learn more about Paint War.  And don’t forget to give it a try!

Paint War

PaintWar

PaintWar

PaintWar

PaintWar

qTrace is released!

December 5th, 2011 Buu Nguyen No comments

After quite some time working on it, we finally released qTrace 1.0, the defect reporting tool you want to have ;) .

To find out more and download the trial version, please visit http://www.qasymphony.com.

Pro iOS Apps Performance Optimization

December 3rd, 2011 Buu Nguyen No comments

My former student and colleague, Khang Vo, has just published a book on iOS performance optimization. Congratulations to him!

Categories: Mobile Tags: , ,

Training screen casts (in Vietnamese) about C#, ASP.NET MVC, LINQ and Combres

August 15th, 2011 Buu Nguyen 7 comments

The series of MVC/C#/LINQ/Combres screen-casts (in Vietnamese) I produced for Microsoft Vietnam a while a go. Microsoft Vietnam recently allowed CiOne to distribute on their website so that everyone can access for free.

On Becoming a Technical Lead

August 1st, 2011 Buu Nguyen 4 comments

Presentation I gave at the Success in IT Career event organized by KMS Technology last Saturday.

Categories: Uncategorized Tags: , , ,

C# Training for Microsoft Customers

June 16th, 2011 Buu Nguyen 1 comment

Slides for the C# training I conducted for Microsoft’s customers in Ho Chi Minh city on June 9th 2011. The training covered C# 3.0, LINQ, C# 4.0 and Dynamic Binding.

Some pictures of the training
Me

Me

Me

ASP.NET jQuery Cookbook

May 9th, 2011 Buu Nguyen No comments

Another book of which I was the technical reviewer was published: ASP.NET jQuery Cookbook. Access to the link to find out more about the book.

aspnetjquerycookbook

Categories: Uncategorized Tags: , ,

A catch-all .NET delegate and event handler

April 15th, 2011 Buu Nguyen No comments

In a current project, I need to build a catch-all handler which could be used to wired to any static or instance delegate and event regardless of the actual delegate/event type.

For example, given the following definitions:

private delegate int Op(int i);
private delegate int BinaryOp(int i, int j);
class Test
{
    public Op OpDelegate;
    public event BinaryOp BinaryEvent;
}

I want to be able to write code like this:

obj.AddHandler("OpDelegate", args => (int)args[0] * (int)args[0]);
obj.AddHandler("BinaryEvent", args => (int)args[0] + (int)args[1]);

In the above code segment, code>obj is an instance of the Test class. AddHandler should be an extension method for object class. The parameters include the name of the delegate or event and a catch-all handler of type Func<object[], object> and this handler might have been bound to some target. In addition, the code in question mustn't need to know about the actual type of obj at compile time nor does it need to know about the actual signature of the delegate and event being wired.

What AddHandler needs to do is creating some delegate matching the definition of the delegate/event being wired and have that delegate forward the call to the Func<object[], object> argument. That calls for a bit of code generation to build a delegate instance from a runtime generated method definition (which will have its signature match the delegate/event being wired). Like when developing Fasterflect, I opt for CIL generation.

The code for the solution is below. I will incorporate it into Fasterflect as an add-on service. Note that it makes use the EmitHelper class which could be found here.

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using Emitter;

public static class DynamicHandler
{
    public static Type AddHandler(this Type targetType, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(targetType, fieldName, func, null, true);
    }

    public static Type AssignHandler(this Type targetType, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(targetType, fieldName, func, null, false);
    }

    public static Type AddHandler(this object target, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(target.GetType(), fieldName, func, target, true);
    }

    public static Type AssignHandler(this object target, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(target.GetType(), fieldName, func, target, false);
    }

    private static Type InternalAddHandler(Type targetType, string fieldName,
        Func<object[], object> func, object target, bool combine)
    {
        Type delegateType;
        var eventInfo = targetType.GetEvent(fieldName);
        if (eventInfo != null && !combine)
            throw new ArgumentException("AssignHandler cannot be used for event type");

        if (eventInfo != null)
        {
            delegateType = eventInfo.EventHandlerType;
            var dynamicHandler = BuildDynamicHandler(targetType, delegateType, func);
            eventInfo.GetAddMethod().Invoke(target, new Object[] {dynamicHandler});
        }
        else
        {
            var fieldInfo = targetType.Field(fieldName,
                                                target == null
                                                    ? Flags.StaticAnyVisibility
                                                    : Flags.InstanceAnyVisibility);
            var field = !combine ? null : target == null
                                            ? (Delegate) fieldInfo.Get()
                                            : (Delegate) fieldInfo.Get(target);
            delegateType = fieldInfo.FieldType;
            var dynamicHandler = BuildDynamicHandler(targetType, delegateType, func);
            field = field == null
                        ? dynamicHandler
                        : Delegate.Combine(field, dynamicHandler);
            (target ?? targetType).SetFieldValue(fieldName, field);
        }
        return delegateType;
    }

    public static Delegate BuildDynamicHandler(this Type delegateOwnerType, Type delegateType,
        Func<object[], object> func)
    {
        MethodInfo invokeMethod = delegateType.GetMethod("Invoke");
        Type returnType = invokeMethod.ReturnType;
        bool hasReturnType = returnType != Constants.VoidType;
        var paramTypes = invokeMethod.GetParameters().Select(p => p.ParameterType).ToArray();
        var dynamicMethod = new DynamicMethod("add_handler",
                                                hasReturnType ? returnType : null,
                                                new [] {typeof(Invoker)}.Concat(paramTypes).ToArray(),
                                                delegateOwnerType);
        var il = new EmitHelper(dynamicMethod.GetILGenerator());
        il.ldarg_0.end(); // <this>
        il.DeclareLocal(typeof(object[]));
        il.ldc_i4(paramTypes.Length); // <this> <length>
        il.newarr(typeof(object)); // <this> <arr>
        il.stloc_0.end(); // <this>
        for (int i = 0; i < paramTypes.Length; i++)
        {
            il.ldloc_0 // <this> <arr>
                .ldc_i4(i) // <this> <arr> <i>
                .ldarg(i + 1) // <this> <arr> <i> <arg_i+1>
                .boxIfValueType(paramTypes[i]) // <this> <arr> <i> <boxed_if_value:arg_i+1>
                .stelem_ref.end(); // <this>
        }
        il.ldloc_0.end(); // <this> <arr>
        il.callvirt(Invoker.InvokeMethodInfo); // <ret>
        if (hasReturnType)
            il.unbox_any(returnType).ret();
        else
            il.pop.ret();
        return dynamicMethod.CreateDelegate(delegateType, new Invoker(func));
    }

    public class Invoker
    {
        public static readonly MethodInfo InvokeMethodInfo =
            typeof(Invoker).Method("Invoke", Flags.InstanceAnyVisibility);
        private readonly Func<object[], object> func;

        public Invoker(Func<object[], object> func)
        {
            this.func = func;
        }

        public object Invoke(object[] args)
        {
            return func(args);
        }
    }
}
Categories: .NET Tags: , , ,

I’m a Microsoft MVP, again

April 4th, 2011 Buu Nguyen 6 comments

I’ve just got news from Microsoft that I am, once again, a Microsoft MVP in ASP.NET/IIS (formerly ASP/ASP.NET).  This is exciting news.  A big thanks to all Microsoft employees and community members who have worked with me in various projects during the past year.

MVP-h-550x222

Categories: .NET Tags: ,

Speech at startup offline event

March 23rd, 2011 Buu Nguyen 5 comments

Slides for my speech at an offline event about startups in Ho Chi Minh City.

View more presentations from Buu Nguyen