Archive

Archive for the ‘open source’ Category

.NET Reflection Made Fast & Simple – Fasterflect 1.1 Release

November 19th, 2009 Buu Nguyen 7 comments

I’m pleased to announce that version 1.1 of Fasterflect, the fast & 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, including its design, APIs, and benchmark, please refer to this Code Project article.

Changes since version 1.0 beta (the one documented in the Code Project article) include:

  • Support array types (construction, set element, get element)
  • Support structs
  • Support ref/out parameters
  • Support lookup by covariant parameter type
  • Inference of parameter types for non-null arguments
  • Several bug fixes

Sample Code

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;
    }
}
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;
    }
}
class Program
{
    static void Main()
    {
        // Load a type reflectively, just to look like real-life scenario
        var types = new[]
                        {
                            Assembly.GetExecutingAssembly().GetType("FasterflectSample.PersonClass"),
                            Assembly.GetExecutingAssembly().GetType("FasterflectSample.PersonStruct")
                        };
        Array.ForEach(types, type =>
                                 {
                                     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<int>("InstanceCount") == 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<int>("InstanceCount"));

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

        // We can bypass the constructor to change the value of Person.InstanceCount
        type.SetField("InstanceCount", 2);
        AssertTrue(2 == type.GetField<int>("InstanceCount"));

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

        // Now, let's retrieve Person.InstanceCount via the static method GetInstanceCount
        AssertTrue(4 == type.Invoke<int>("GetInstanceCount"));

        // 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("GetInstanceCount")
                            .Invoke("GetInstanceCount")
                            .Invoke<int>("GetInstanceCount"));

        // Invoke method receiving ref/out params, we need to put arguments in an array
        var arguments = new object[] { 1, 2 };
        type.Invoke("Swap",
            // 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, "Doe");

        // 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<int>("id"));
        AssertTrue("Doe" == obj.GetProperty<string>("Name"));

        // Let's use the indexer to retrieve the character at index 1
        AssertTrue('o' == obj.GetIndexer<char>(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<int>("id"));
        AssertTrue(null == obj.GetProperty<string>("Name"));

        // Now, modify the id
        obj.SetField("id", 2);
        AssertTrue(2 == obj.GetField<int>("id"));
        AssertTrue(2 == obj.GetProperty<int>("Id"));

        // We can chain calls
        obj.SetField("id", 3).SetProperty("Name", "Buu");
        AssertTrue(3 == obj.GetProperty<int>("Id"));
        AssertTrue("Buu" == obj.GetProperty<string>("Name"));

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

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

        // Double-check the current value of the milesTravelled field
        AssertTrue(6 == obj.GetField<int>("milesTraveled"));

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

        // Get & 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<object>(4)));
            AssertTrue(obj.Equals(arr.GetElement<object>(9)));
        }
        else
        {
            AssertTrue(obj == arr.GetElement<object>(4));
            AssertTrue(obj == arr.GetElement<object>(9));
        }

        // Remember, struct array doesn't have null element
        // (instead always initialized to default struct)
        if (!isStruct)
        {
            AssertTrue(null == arr.GetElement<object>(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("InstanceCount");

        // 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 =>
        {
            object obj = ctor(i, "_" + i).CreateHolderIfValueType();
            AssertTrue(++currentInstanceCount == (int)count());
            AssertTrue(i == obj.GetField<int>("id"));
            AssertTrue("_" + i == obj.GetProperty<string>("Name"));
        });

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

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

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

    public static void AssertTrue(bool expression)
    {
        if (!expression)
            throw new Exception("Not true");
        Console.WriteLine("Ok!");
    }
}
  • Share/Bookmark

Combres – WebForm & MVC Client-side Resource Combine Library

November 4th, 2009 Buu Nguyen No comments

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:

  • Organize resource files, including JavaScript and CSS, into separate resource sets, each may share the same or use different configuration settings.
    • ConfigConfiguration settings are specified in an XML file which is monitored by Combres so that changes get noticed and applied immediately.
    • Resource files can be static files in the web server, dynamically generated files, or remote files from external servers or web applications.
  • 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’s performance rules #1, #4 and #10 to know why this is useful.)
    • The minification part is performed by the great YUI Compressor library.
  • Generate proper ETag and Expires/Cache-Control headers for every response as well as support server-side caching. (Refer to Yslow’s performance rules #3 and #13 to know why this is useful.)
  • Integrated with ASP.NET routing engine and thus work equally well for both ASP.NET MVC and ASP.NET WebForm applications.
  • Support Debugging mode, which won’t cache or minify contents at all to facilitate debugging.
  • 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.

I wrote about how to use and enhance this library in this Code Project article.

You can also get the binary, source code and sample from these links:

  • Share/Bookmark

ASP.NET MVC Validation Library

February 10th, 2009 Buu Nguyen 2 comments

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’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 library:

  • Built for MS Validation Application Block. (Emad Ibrahim’s library targets Castle’s validation framework. Check out his library if you need this feature.)
  • 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 Password field of the User entity).
  • 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.
  • 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.

How does it work?
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’s say you have a User entity in your application, you can annotate it as follows:

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; }
}

Now, whenever this entity is populated with form posted values, you can perform server-side validation by invoking the Validate() extension method on the entity. Let’s do that in the action method.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditUser([Bind(Prefix="")]User user)
{
     try
     {
          user.Validate<User>();
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}

The above code will perform validation on the entity given its validation attributes. If there’s any validation error, an EntityValidationException object is thrown and you can use it the populate the model state with error messages. The method PopulateWithErrors is another extension method provided by the library.

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 Validate() method.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangePassword([Bind(Prefix="")]User user)
{
     try
     {
          // Only validate the password property
          user.Validate<User>(new[] {"password"});
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}

I could have added a custom model binder to the library so that validation happens at the model binding phase but I think that’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.

Let’s see the result of the server-side validation:

Okay, let’s move to client-side validation. The trick behind the client-side validation is that the view will invokes the HtmlHelper’s ClientSideValidation() extension method which will retrieve all validation attributes of the specified entity type (e.g. User) and generate equivalent client-side validation script for them.

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.)

There are a couple of overloads of the ClientSideValidation() method:

// Generates validation script for the User type
Html.ClientSideValidation<User>();

// Generates validation script for the User type, including the code to initialize form validation
Html.ClientSideValidation<User>(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<User>(bool ignoreMissingElements);

// See the above 2 overloads
Html.ClientSideValidation<User>(string formName, bool ignoreMissingElements);

For example, the generated code for an invocation of the second overload will result in the following code:

<script language="JavaScript"><!--
$().ready(function() {

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

	}
});

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

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

	}
});

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

});
--></script>

That’s it, you don’t need to write a single line of JavaScript to have this nice client-side validation:

How can I download and use it?
The library is hosted at CodePlex. 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 & hope you’ll find the library useful.

  • Share/Bookmark