/// Tuesday, December 6

Object<T>

It's good practice to override Equals() and GetHashCode() in your classes. Well, that's what they say anyway, I rarely do. But, with generics and org.apache.commons.lang.builder.HashCodeBuilder (one of my java ports) it's easy to do. I created a generic base Object class:

public class Object<T> {
    public override int GetHashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    public bool Equals(T obj) {
        if (obj == null) {
            return false;
        }
        return obj.GetHashCode() == GetHashCode();
    }

    public override bool Equals(object obj) {
        if (obj == null) {
            return false;
        }

        if (obj is T) {
            return GetHashCode() == obj.GetHashCode();
        }
        else {
            return false;
        }
    }
}

HashCodeBuilder.reflectionHashCode(this) introspects all the fields of the class and creates a HashCode. To create a class with this functionality, derive from Object<T>:

public class Book : Object<Book> {
    string author = null;
    public string Title = null;
    public string Author {
        get { return author; }
        set { author = value;}
    }
}

This trick is great for unit testing where you need to compare the inner value of classes. Unfortunately you can seldom use this trick in C#, a single-inheritance language, unless you're building a framework and you derive from a single base. For performance, use HashCodeBuilder's append functions instead of reflection.

I Miss Java

While I have a lot more experience with C# and .NET, I have good experience with Java. I like both C# and Java. I especially like Java for open-source. There's so many well-designed open-source Java projects. Whatever open source projects there are for .NET, there's bound to be a multitude of projects that are stable and more mature on the Java side. And there are many Java projects that simply do not have a counterpart on the .NET side. One library I really miss is Jakarta Commons, a comprehensive set of utility classes for your day to day coding. I'm porting functions/classes as I need them. Fortunatley, the MS Java Conversion assistant is helping in this effort, doing most of the work.

/// Sunday, December 4

Switching to LGPL

After reading the history of AJAX.NET it really bothers me that open-source on the .NET is greedy. Many open-source .NET projects that have become successful have turned commercial leaving behind many developers who contributed, tested and offered ideas while it was open source. What a shame. There are many projects that are close-sourced and proclaim to be free for .NET. You're a SUCKER if you're contributing your time to one of these projects.

I'm switching all my open-source projects to LGPL, GNU Lesser General Public License. This means you can use the library as-is in a commercial application without any issues and give credit in a credits.txt file. You can't create a derivative of it by changing the source, recompiling and using it commercially without my permission. If you fix bugs or enhance it, then send a diff of those modifications and you are granted automatic permission to use the libary commercially again. I don't care about your proprietary code, only changes/enhancements to the library. I think this is more than fair. I'm not sure if LGPL is the right license for all I said, but it's a good start.

JSON Serializer/Deserialier

I have a working JSON (JavaScript Object Notation) serializer/deserializer for .NET. I can marshall complex types between the browser and server using JSON. This is for my AJAX Behaviour.NET library but like all my stuff you're free to use under the terms of the license. This was not an easy task. JSON is typeless which makes it very difficult to deserialize into strongly typed language like C#. I resorted to encoding the type of an object or array (collection) into the document itself:

{
    "__objtype__" : "Test.Amelgy.Ajs.Json.Person, Test.Amelgy.Ajs",
    "Name" : null,
    "Sex" : "\u0000",
    "__arrtype__Pets" : "System.String[], mscorlib",
    "Pets" : [
        "sam-sam",
        "chili"
    ],
    "__arrtype__Books" : "System.Collections.ArrayList, mscorlib",
    "Books" : [
        {
            "__objtype__" : "Test.Amelgy.Ajs.Json.Book, Test.Amelgy.Ajs",
            "Author" : "Tom Archer",
            "Title" : "Inside C#"
        },
        {
            "__objtype__" : "Test.Amelgy.Ajs.Json.Book, Test.Amelgy.Ajs",
            "Author" : "GOF",
            "Title" : "Design Patterns"
        }
    ],
    "Weight" : 160
}

This has potential for a security risk, but I'll give the end developer an option to encrypt the type and assembly. Deserializing is a matter of building C# code and using the CSharpCodeDom to compile it. Here's a sample of C# code generated by the deserializer. Still very readable, good for debugging.

namespace nsc2fc87b2d1d5450a8080dd6f0168da50 { class Foo { public object GetObject() {
Test.MGutz.Json.Person object0 = new Test.MGutz.Json.Person();
object0.Name = null;
object0.Sex = "\u0000";
System.String[] array1 = new System.String[2];
object0.Pets = array1;
array1[0] = "sam-sam";
array1[1] = "chili";
System.Collections.ArrayList array2 = new System.Collections.ArrayList();
object0.Books = array2;
Test.MGutz.Json.Book object3 = new Test.MGutz.Json.Book();
array2.Add(object3);
object3.Author = "Tom Archer";
object3.Title = "Inside C#";
Test.MGutz.Json.Book object4 = new Test.MGutz.Json.Book();
array2.Add(object4);
object4.Author = "GOF";
object4.Title = "Design Patterns";
object0.Weight = 160;
return object0; }}}

The only remaining issue is nested anonymous arrays. That'll be ugly cuz I think I'm too far in the parser and I'm using my JsonTextWriter which is not random access. A slight challenge is all.

{
    "__arrtype__nested" : "ArrayList, mscorlib : int[], mscorlib"
    "nested" = [
        [1, 2, 3]
    ]
}

ASP.NET aaargh!

I'm deciding how to expose server-side methods to AJAX clients of non-Gamba developers. I want Behaviour.NET to be usable outside of Gamba. AJAX is easy for Gamba or any MVC2 framework for that matter. A controller can expose any combination of views or methods. In Gamba's case, a server-method's logic is as simple as changing the response content type to Content.TextPlain, Content.TextXml or the default Context.TextHtml then return data directly bypassing the usual logic of rendering views.

In ASP.NET you don't get a controller, you get a stupid page. I have some options. I can derive from the ASP.NET Page to create a BehaviourPage. Developers then change their code behind to inherit from BehaviourPage. This lets me create a page controller for pages taking advantage of Behaviour.NET. Remote call would need be encoded in the query string of that page. But, what if a shop already has custom page in place? This folks is one of the many reasons why the ASP.NET page framework sucks!

The other option is to commandeer the .ashx extension and create an MVC framework strictly for AJAX methods like web services does with .asmx. I could use a different extension but .ashx is supported natively by ASP.NET. Using a different extension would prohibit its use in a hosted environment where you can't change IIS mappings. Even worse, .ashx may already be in use.

Yet another option is to hook into the lifecycle events. Seems too manual for me, but it maybe the only option I have.

If anyone has any other suggestion please speak up. It's why I think aloud on my blog. It's a think-tank.

I've told some people interested in this library it would take about a week to create a standalone version of Behaviour.NET. I forgot about the pains of ASP.NET. I'll get it out guys. I want to make it simple for you, so don't shoot me if it's not out in a week.

/// Saturday, December 3

Behaviour.NET - Real Open Source AJAX for .NET

Real open source meaning Apache License 2.0 instead of the mess with AJAX.NET.

So I thought I had discovered a better way to do AJAX. Well, it looks like the MS Atlas folks and I think alike. I haven't really looked Atlas, and today I saw a screenshot of it with the word behaviour. What's funny is behaviours are the foundation of Behaviour.NET, a standalone AJAX library for my Gamba framework. I'd have to look at some samples to verify. What is that old adage? "Great minds think alike." I won't go that far, but this seems a better approach than what I've seen.

If you remember my previous article Helpers or Components? I could not decide whether to create an AJAX API using helper functions or a lightweight component framework. After some contemplation it's my humble opinion helper functions are evil. We're back to ASP spaghetti again. Let's compare the two approaches, here's the helper function style:

class Test(AjaxController):
    def Foo():
        ViewMethod = FooView

    def SayHello() as string:
        ContentType = Content.TextPlain
        return "Hello world!"
<!-- Test.FooView.tpl -->
<%= CreateButtonDoRemote("Invoke Remote", Urlize("SayHello")
        , {"onsuccess" : "$('input1').value = request.responseText;"
        , "onfailure" : "alert('Unable to get information from server.')"}
    )
%> &nbsp; <input id="input1"/>

It's typical ASP coding. Here's how it's done with Behaviour.NET, with behaviours code residing in the controller.

class Test(AjaxController):
    def Foo():
        button = Button("button1")
        with method = RemoteMethod(Test, "SayHello"):
            OnSuccess += Prototype.SetValue("input1")
            OnFailure += Prototype.MsgBox("Unable to get information from server.")
        button.OnClick += Prototype.InvokeRemote(method)

        Behaviours.AttachBehaviour(button)
        ViewMethod = FooView

    def SayHello():
        ContentType = Content.TextPlain
        return "Hello world!"
<!-- Test.FooView.tpl -->
<input id='button1' type='button' value="Invoke Remote"/> &nbsp; <input id="input1"/>

It's a little bit more coding, but here are some advantages off the top of my head

One disadvantage is a slight performance loss, but that's minimal. I've looked at some implementations of AJAX generic helper functions and they use a maze of functions to generate a script. These objects are very light and for now all they do is encapsulate some javascript code. This lightweight component framework coincidentally fits in very well with Gagamba, my plans for a fully componentized version of Gamba. I wanted to do a basic core framework first before starting Gagamba.

Oh, I almost forgot. Thanks to Ben Nolan, the author of the Behaviour JavaScript library for inspiration.

/// Friday, December 2

Gamba: A New Beginning

Hmm, maybe Boo is a language for three developers (quote from somewhere). Noone seems to be interested in a web framework for Boo. Eventually I'd like to enlist people to contribute but I dont see much interest. That's a little disconcerting, but time to move on. Maybe I'll contribute to Boo in other ways, but for now I'll concentrate on C#. Boo's architect, bamboo, has some good ideas with Boo but I don't think people realize how things like AstAttributes let you be more expressive and creative. Code injection, for example, is very powerful. You can get close with an MSBuild preprocessor and partial classes with C# 2.0 but you don't get the AST. I've only touched the surface, you could change the behaviour of a class instead of just mixing in other behaviour. Anyway, it's all for not.

If you're interested in Boo for web stuff you still have Brail and MonoRail.

I still have plans for Gamba, which as of today starts anew with focus on ASPX pages, MS Enterprise Blocks and C#. My real experience lies in enteprise development and so it's my comfort zone. Sadly, I can only do a pseudo-MVC2 approach but it fits in well with how most Microsoft developers do web development.

Gamba: Helpers or Components?

I can't decide how Gamba should present AJAX to the end developer. After analyzing the prototype javascript library, which is the foundation for most AJAX functionality these days, should Gamba provide helper functions or create a component model? AJAX lends itself to the component model. You're forced to deal with synchronous/ asynchronous events. Events fired by one element may result in the update of another element. For example, clicking a button calls a remote function updating an input box.

Gamba can follow MonoRail and provide helper functions. This requires the developer to learn the prototype javascript library. Gamba can shield the end developer by creating a bunch of helper functions as MonoRail does. Here's an example:

<%= CreateButtonDoRemote("Invoke Remote", Urlize("SayHello")
        , {"onsuccess" : "$('input1').value = request.responseText;"
        , "onfailure" : "alert('Unable to get information from server.')"}
    )
%> &nbsp; <input id="input1"/>

It's just not simple, which goes against the KISS principle. The other option is to create a lightweight component model with pseudo-events. Here's the equivalent behaviour as above:

<%
text = TextBox('input1')
with button = Button(Caption: 'Invoke Remote'):
    OnClick += Client.CallRemote(Urlize('SayHello'))
    OnSuccess += Client.SetValue(text)
    OnFailure += Client.MsgBox('Unable to get information from server.')
%>

${button} &nbsp; ${text}

This page is powered by Blogger. Isn't yours?