Spot the web RSS 2.0
# Monday, March 17, 2008

If you've done any Ajax development then you know that much of the loading of data is done in the background. This is great from a developers stand point, but from a users stand point it can be confusing as to what is happening while the data is being loaded. The solution to this is to show a loading indicator.

A loading indicator is a great idea and a nice animated image that could be hidden would be nice. However, if you are like most developers making a nice animated image may not be your strongest point. Well, today while seeing what was getting bookmarked on del.icio.us, using the del.icio.us Spy, I found an interesting and simple service that makes it very easy to get a nice looking loading indicator.

The service is call Ajaxload and is very easy to use. You simply choose the loading icon that you like and the background/foreground colors (you can even have the background transparent). Then you just save it to your computer using the "Download It" button and then you have your own customized loading indicator.

You can go to the service by clicking here.

If you have used this or a similar service I would love to hear about your experience with it (you can leave a comment, or if you would like you can write a blog post about it on this blog, using your free Ajaxonomy account). So, remember that your users would love to see a loading indicator when it is appropriate.

Monday, March 17, 2008 10:33:41 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
AJAX | Programming | Web 2.0 | Web Design
# Monday, March 10, 2008

This article discusses the delegate type and how it can be used to point to methods in the application which can be invoked at later time. This article demonstrates also the delegate ability to multicast and delegate covariance.

A delegate is a type-safe object that can point to another method (or possibly multiple methods) in the application, which can be invoked at later time.

Delegates also can invoke methods Asynchronously.

A delegate type maintains three important pices of information :

  1. The name of the method on which it make calls.
  2. Any argument (if any) of this method.
  3. The return value (if any) of this method.

Defining a Delegate in C#

when you want to create a delegate in C# you make use of delegate keyword.

The name of your delegate can be whatever you desire. However, you must define the delegate to match the signature of the method it will point to. fo example the following delegate can point to any method taking two integers and returning an integer.

public delegate int DelegateName(int x, int y);

A Delegate Usage Example

namespace MyFirstDelegate

{

    //This delegate can point to any method,

    //taking two integers and returning an

    //integer.

    public delegate int MyDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static int Add(int x, int y)

        {

            return x + y;

        }

        public static int Multiply(int x, int y)

        {

            return x * y;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MyDelegate

            //that points to MyClass.Add().

            MyDelegate del1 = new MyDelegate(MyClass.Add);

            //Invoke Add() method using the delegate.

            int addResult = del1(5, 5);

            Console.WriteLine("5 + 5 = {0}\n", addResult);

            //Create an Instance of MyDelegate

            //that points to MyClass.Multiply().

            MyDelegate del2 = new MyDelegate(MyClass.Multiply);

            //Invoke Multiply() method using the delegate.

            int multiplyResult = del2(5, 5);

            Console.WriteLine("5 X 5 = {0}", multiplyResult);

            Console.ReadLine();

        }

    }
}

Delegate ability to Multicast

Delegate ability to multicast mean that a delegate object can maintain a list of methods to call, rather than a single method
if you want to add a method to the invocation list of a delegate object , you simply make use of the overloaded += operator, and if you want to remove a method from the invocation list you make use of the overloaded operator -= .

Note:Multicast delegate must contain only methods that return void, or you will get a run time exception.

A Multicast Delegate Example

namespace MyMulticastDelegate

{

    //this delegate will be used to call more than one

    //method at once

    public delegate void MulticastDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static void Add(int x, int y)

        {

            Console.WriteLine("You are in Add() Method");

            Console.WriteLine("{0} + {1} = {2}\n", x, y, x + y);

        }

        public static void Multiply(int x, int y)

        {

            Console.WriteLine("You are in Multiply() Method");

            Console.WriteLine("{0} X {1} = {2}", x, y, x * y);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MulticastDelegate

            //that points to MyClass.Add().

            MulticastDelegate del = new MulticastDelegate(MyClass.Add);

            //using the same instance of MulticastDelegate

            //to call MyClass.Multibly() by adding it to it's

            //invocation list.

            del += new MulticastDelegate(MyClass.Multiply);

            //Invoke Add() and  Multiply() methods using the delegate.

            //Note that these methods must have a void return vlue

            Console.WriteLine("****calling Add() and Multibly() Methods.****\n\n");

            del(5, 5);

 

            //removing the Add() method from the invocation list

            del -= new MulticastDelegate(MyClass.Add);

            Console.WriteLine("\n\n****Add() Method removed.****\n\n");

            //this will invoke the Multibly() method only.

            del(5, 5);

        }

    }

}

Delegate Covariance

Assume you are designing a delegate that can point to methods returning a custom class type:

//Define a delegate pointing to methods returning Employee types.

public delegate Employee EmployeeDelegate();

if you were to derive a new class from Employee Type named SalesEmployee and wish to create a delegate type that can point to methods returning this class type you would be required to define an entirely new delegate to do so

//a new  delegate pointing to methods returning SalesEmployee types.

public delegate SalesEmployee SalesEmployeeDelegate();

Example

namespace MyEmployeesDelegate

{

    //Define a delegate pointing to methods returning Employee types.

    public delegate Employee EmployeeDelegate();

    //a new  delegate pointing to methods returning SalesEmployee types.

    public delegate SalesEmployee SalesEmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate empDel = new EmployeeDelegate(GetEmployee);

            Employee emp = empDel();

            SalesEmployeeDelegate salesEmpDel = new SalesEmployeeDelegate(GetSalesEmployee);

            SalesEmployee emp2 = salesEmpDel();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

 

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

It would be ideal to build a single delegate type that can point to methods returning either Employee or SelesEmployee types.
Covariance allows you to build a single delegate that can point to methods returning class types related by classical inheritance.

Delegate Covariance Example

namespace DelegateCovariance

{

    //Define a single delegate that may return an Employee

    // or SalesEmployee

    public delegate Employee EmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate emp = new EmployeeDelegate(GetEmployee);

            Employee emp1 = emp();

            EmployeeDelegate empB = new EmployeeDelegate(GetSalesEmployee);

            //to obtain a derived type you must perform an explicit cast.

            SalesEmployee emp2 = (SalesEmployee)empB();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

I hope you are now have a good idea with the creation and usage of delegates types.

Monday, March 10, 2008 10:28:46 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | AJAX | Microsoft | Programming | C#
# Sunday, March 09, 2008

A common - and desirable - technique for constructing JavaScript-based web applications is that of progressive enhancement: only providing capable browsers with the features that they are capable of utilizing - but providing incapable browsers with an adequate, albeit degraded, experience otherwise.

This provides the best of both worlds: Users of modern browsers (the majority audience) can get the best experience while those that are using incapable browsers (such as most mobile devices) will still get an interface that suits them well.

There's one thing, overriding in all of this, however: Progressive enhancement is nearly only ever applied to the JavaScript functionality of web applications. Presumably it's assumed that if a browser is capable of supporting the desired JavaScript features of an application then it must, also, be capable of supporting the specific CSS styling as well.

One technique that has greatly interested me, as of late, is one employed by the Filament Group (a local design shop here in Boston): Progressive CSS Enhancement. The premise is that progressive enhancement is done with page styling in mind, primarily, rather than from a purely-JavaScript perspective.

This is particularly important for a couple reasons:

  • It should be easy to degrade page styling in a manner that isn't reliant upon CSS browser hacks - this technique makes it so.
  • Not all pages utilize heavy JavaScript (and, thus, progressive JavaScript enhancement does not apply to them).

Their technique works as follows: You choose to provide the user with, either, the enhanced or the decreased experience by default. In either case a basic script is run which attempts to verify a couple CSS styling behaviors along with some basic JavaScript functionality (just enough to be able to run the test).

A couple of the CSS techniques that they test for:

  • Box model: make sure the width and padding of a div add up properly using offsetWidth.
  • Positioning: position a div and check its positioning using offsetTop and offsetLeft.
  • Float: float 2 divs next to each other and evaluate their offsetTop values for equality.
  • Clear: test to make sure a list item will clear beneath a preceding floated list item.
  • Overflow: wrap a tall div with a shorter div with overflow set to 'auto', and test its offsetHeight.

With those in place you can pretty safely begin designing a useful CSS-based layout. Note that the experience will only ever be upgraded if all of the tests pass - if any fail then it simply won't continue. Obviously there'll still exist some browser discrepancies (like in the differences in the box model between Internet Explorer 6 and most other browsers) but that's usually an acceptable level of hackage (meaning that you won't have to deviate much from what you're already doing).

The actual implementation is quite simple. It consists of a number of JavaScript-based rules that test for behavior. For example the following rule tests for a working box model:

var newDiv = document.createElement('div');
document.body.appendChild(newDiv);
newDiv.style.visibility = 'hidden';
newDiv.style.width = '20px';
newDiv.style.padding = '10px';
var divWidth = newDiv.offsetWidth;
if(divWidth != 40) {document.body.removeChild(newDiv); return false;}

That check, alone, is able to knock off a number of older browser whom aren't able to successfully implement that CSS behavior. Currently all the rules are in a large code block, which makes maintenance unwieldily. I think that this library could definitely benefit from extensibility (being able to add/remove rules that you wish to honor).

When it comes time to actually use this technique within your application there are a number of strategies that you can use. However, for the sake of discussion here, let's assume that you're sending, by default, the degraded experience to the client (optionally upgrading if the browser is capable). Then you would be able to use these two techniques:

  • A class of "enhanced" is assigned to the body element to be used for optional CSS scoping (such as: body.enhanced {background: red;}).
  • Any links to alternate stylesheets that have a class of "enhanced" will be enabled.

In this manner you can specify all of your stylesheets in your header with some disabled (being alternate stylesheets) or with some CSS rules being only applied with the body.enhanced match.

Their implementation also allows you to only execute JavaScript if all the rules pass - however I'm not sure if that's an acceptable solution, in this situation. If you want to verify that your desired JavaScript functionality is able to operate then you should check for just that. However, in this case, we can get the other side of the equation: Verifying that CSS works as you would expect it to, knowing that an adequate experience can be provided.

If you're curious as to which devices are supported by the default rules in the test file you can view the result matrix on the tool's site.

I definitely think that this technique has a lot of merit, especially in the realm of mobile-accessible web sites. Since it's virtually impossible to design, and test, your pages to work on such a large number of obscure platforms this degraded strategy is really one that will help to benefit both you, and your users, in the long run.

Sunday, March 09, 2008 11:24:37 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Programming | Web Design
# Friday, March 07, 2008

This article explains how you can extract all Tables, including Data, to an Excel file. Every Table will have it's own worksheet. The code does need an excel application installed on the server, while it's using Office Interop.

To get this code to work, you need to add a reference to Excel.dll by using Add Reference on the project and selecting Microsoft Excel 9.0 (or 10.0) Object Library from the COM tab on the Add Reference dialog.

And then import the following namespace:

Imports System.Runtime.InteropServices.Marshal


Now add the following class to your project:

Private Sub create(ByVal sDatabaseName As String)
Dim dsTables As DataSet = New DataSet

'Get all Tables from database
dsTables = getAllTables(sDatabaseName)
'Create Excel Application, Workbook, and WorkSheets
Dim xlExcel As New Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlBook As Excel.Workbook
Dim tblSheet As Excel.Worksheet
Dim xlCells As Excel.Range
Dim sFile As String

'File name for the excel file
sFile = Server.MapPath("~\Sheets\" & sDatabaseName & "_data.xls")

xlExcel.Visible = False : xlExcel.DisplayAlerts = False
xlBooks = xlExcel.Workbooks
xlBook = xlBooks.Add

For i As Integer = 0 To dsTables.Tables.Count - 1
    tblSheet = xlBook.Worksheets.Add
    tblSheet.Name = dsTables.Tables(i).TableName
    xlCells = tblSheet.Cells
    'Fill all cells with data
    GenerateExcelFile(dsTables.Tables(i), xlCells)
Next

'Remove initial excel sheets. Within a try catch because the database
'could be empty (a workbook without worksheets is not allowed)
Try
    Dim
SheetCount As Integer = xlExcel.Sheets.Count
    CType(xlExcel.Sheets(SheetCount - 0), Excel.Worksheet).Delete()
    CType(xlExcel.Sheets(SheetCount - 1), Excel.Worksheet).Delete()
    CType(xlExcel.Sheets(SheetCount - 2), Excel.Worksheet).Delete()
Catch ex As Exception

End Try

'Save the excel file
xlBook.SaveAs(sFile)

'Make sure all objects are disposed
xlBook.Close()
xlExcel.Quit()
ReleaseComObject(xlCells)
ReleaseComObject(tblSheet)
ReleaseComObject(xlBook)
ReleaseComObject(xlBooks)
ReleaseComObject(xlExcel)
xlExcel = Nothing
xlBooks = Nothing
xlBook = Nothing
tblSheet = Nothing
xlCells = Nothing
'Let the Garbage Collector know it can get to work
GC.Collect()

'Export Excel for download
Try
HttpContext.Current.Response.ContentType = "application/octet-stream"
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.IO.Path.GetFileName(sFile))
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.WriteFile(sFile)
HttpContext.Current.Response.End()
Catch ex As Exception
'An exception will be thrown, but can just be ignored
End Try

End Sub


To generate the individual sheets, the following Sub is used:

Private Sub GenerateExcelFile(ByRef table As DataTable, ByVal xlCells As Excel.Range)
Dim dr As DataRow, ary() As Object
Dim
iRow As Integer, iCol As Integer

'Output Column Headers
For iCol = 0 To table.Columns.Count - 1
    xlCells(1, iCol + 1) = table.Columns(iCol).ToString
    xlCells(1).EntireRow.Font.Bold =
True
Next

'Output Data
For iRow = 0 To table.Rows.Count - 1
    dr = table.Rows.Item(iRow)
    ary = dr.ItemArray
    For iCol = 0 To UBound(ary)
        xlCells(iRow + 2, iCol + 1) = ary(iCol).ToString
        Response.Write(ary(iCol).ToString & vbTab)
    Next
Next
xlCells.Columns.AutoFit()
End Sub


And now the trick to getting all tables and data from a database:

Public database as String

Public ReadOnly Property getAllTables(ByVal sDB As String) As DataSet
    Get
       
database = sDB
        Dim m_dshelp As DataSet = New DataSet
        getRequestedAllTables(m_dshelp)
        Return m_dshelp
    End Get
End
Property


Private Function getRequestedAllTables(ByRef p_dataset As DataSet) As Boolean

'Retrieve all tablenames from the database:
Dim sSQL As String
Dim
dsTables As DataSet = New DataSet
sSQL =
"SELECT [TableName] = so.name, [RowCount] = MAX(si.rows) " & _
"FROM sysobjects so, sysindexes si " & _
"WHERE so.xtype = 'U' AND si.id = OBJECT_ID(so.name) AND si.rows > 0 " & _
"GROUP BY so.name " & _
"ORDER BY 2 DESC"

getData(sSQL, "Tables", dsTables)

'Loop thrue all tables and do a SELECT *. Then add them to the dataset
For i As Integer = 0 To dsTables.Tables(0).Rows.Count - 1
    sSQL =
"SELECT * FROM " & dsTables.Tables(0).Rows(i).Item(0)
    getData(sSQL, dsTables.Tables(0).Rows(i).Item(0), p_dataset)
Next
End
Function


Private Function getData(ByVal p_sql As String, ByVal p_table As String, ByRef pdataset As DataSet) As Boolean

Dim objDataAdapter As SqlDataAdapter
Dim objcommand As SqlCommand
objcommand
= New SqlCommand(p_sql, getConnection)
objDataAdapter =
New SqlDataAdapter(objcommand)
objDataAdapter.Fill(pdataset, p_table)
End Function


Private Function getConnection() As SqlConnection
If (ConfigurationManager.AppSettings("SQLPW") <> "") Then
    getConnection = New SqlConnection("Server=" & _
    ConfigurationManager.AppSettings("
SQLserver") & ";password=" & _
    ConfigurationManager.AppSettings(
"SQLPW") & "; user=" & _
    ConfigurationManager.AppSettings("
SQLUser") & ";database=" & database)
Else
    getConnection = New SqlConnection("Data Source=" & _
   ConfigurationManager.AppSettings(
"SQLserver") & ";Initial Catalog=" & _
    database &
";Integrated Security=True")
End If
End Function

Friday, March 07, 2008 11:42:11 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Tuesday, March 04, 2008
  1. If your site's content can be turned into a widget somehow, such as with an RSS feed or just a mini version of your site (ex. the puzzles widget on this site) - do so - and then submit your widget to all the major widget-oriented websites such as iGoogle, Netvibes, Pageflakes, Facebook, Live, Widgetbox and Widgipedia - it will help drive a LOT of traffic to your site - think of it as a great form of content syndication.
  2. Do NOT: have a public link exchange on your site, sign your site up on link farms or on SEO directories - this will lower your rankings on Google a lot - take it from experience.
  3. Though CSS can replicate the styling brought from these tags, search bots love them - so they're worth using for SEO purposes: <h1> - <h5>, <strong>, <em>.
  4. Make sure your site supports the big four: Internet Explorer 6+, Firefox 1.5+, Opera, and Safari.
  5. Make sure your site fits down to a 1024 x 768 monitor resolution.
  6. Use the color wheel when creating layout themes. Try to keep your site layout down to three distinct colors.
  7. Create a website shell (a.k.a. template), so that if you decide to make another website down the road, it will be a lot quicker to make because you'll already have a framework set up.
  8. Create a to-do list for your site so you don't forget anything as it grows bigger - I like to jot sudden ideas I get down on it too.
  9. A successful website provides a service to its users - such as teaching (Wikipedia) and/or social networking (Facebook).
  10. Whenever possible, use onmousedown instead of onclick - it's ~100ms faster.
  11. Use file compression for your javascript and web page files so that your pages load faster - also if you can, put the script include tags at the bottom of your page - this will give the illusion that your site loads faster because browsers usually comb through an entire js file before continuing on with loading the rest of your page.
  12. If you have a rails site, I suggest checking out Mongrel and Monit for Mongrel (or God) if you are currently using Apache with FastCGI. You may notice your app is a lot faster with Mongrel clustering than on FastCGI.
  13. This one is more of a for-your-health point, but our eyes naturally look slightly downwards - so if your computer screen is straight in front of you at eye level or higher, trying moving it down to neck or chest level - you may notice that your eyes feel more relaxed -- (I learned this last point from an eye doctor and feel that it helps me.)
Tuesday, March 04, 2008 11:30:24 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | Web Design
# Monday, March 03, 2008

Object oriented programming has been around for quite some time and was made popular by C++ back in the day. Nowadays, even web scripting languages support the paradigm. JavaScript does not have true OO but allows you to use the design pattern in your code. Today, we will dive into using object oriented programming with the popular JavaScript framework Prototype.

Prototype makes it easy to declare your own objects by using the "Class.create()" method:

  1. var sampleObject = Class.create();  


Once you do that you can start writing your class specific methods and properties inside the "prototype" object:

  1. sampleObject.prototype = {   
  2. }  


To declare private properties you simply specify the name of the property followed by a colon and the value:

  1. sampleObject.prototype = {   
  2.     linkIDs: ['mainPageLink''cdmScreenLink''adminLink''helpLink'],   
  3.     statusMessage: '',   
  4.     currentLinkID: 'myLink'  
  5. }  


The important thing to remember is that each property needs to be separated from the next by a comma. As shown above, property values can be a array, a number, a string but cannot be empty value. While:

  1. currentLinkID: 'myLink',  


is valid while


is not.

Declaring your own functions is not any different. Before we look into functions however, there is one function that requires special attention: the "initialize" function:

  1. initialize: function() {   
  2. }  


The initialize function is what JavaScript calls automatically when you create an instance of your object. If you are familiar with OO, this function is the constructor of your object. Any setup and initial requirements for using your object should be done in here.

So to get back to regular functions, they are declared in the format functionName: function() {} as in:

  1. doSomething: function() {   
  2. }  


So far your object should like like this:

  1. var sampleObject = Class.create();   
  2. sampleObject.prototype = {   
  3.     linkIDs: ['mainPageLink''cdmScreenLink''adminLink''helpLink'],   
  4.     statusMessage: '',   
  5.     currentLinkID: 'myLink',   
  6.     initialize: function() {   
  7.     },   
  8.     doSomething: function() {   
  9.     }   
  10. }  


Big deal right, including that in your html page and/or a separate JavaScript file does not do anything for you. The next step in making it of any use is to actually create an instance of the object like so:

  1. var sampleObjectInstance = new sampleObject();  


Creating an instance of the object automatically calls all your code inside the "initialize" function. Here, a good practice is to wrap the creation of your object inside the windows load or dom:loaded (Prototype v1.6) event like:

  1. Event.observe(window, 'load'function() {   
  2.     var sampleObjectInstance = new sampleObject();   
  3. });  


Or

  1. document.observe("dom:loaded"function() {   
  2.     var sampleObjectInstance = new sampleObject();   
  3. });  


To expand on using properties inside your object, whenever you want to access a property such as "currentLinkID", you have to prefix it with "this" as in:

  1. this.statusMessage = 'Who Am I?';  


That is because inside your object's function, without "this", the code does not know about the property. The same applies to using function so you cannot simply called the "doSomething" function with:


but instead if you have to use:

  1. this.doSomething();  

 


This can get a little more complicated when it comes to using event listeners inside your code. Let me elaborate. To tie an event observer that will call the "doSomething" function when a users clicks the link with ID 'myLink', you would usually do:

  1. $(this.currentLinkID).observe('click'this.doSomething);  


While that will work, if you try to access any class properties (such as "statusMessage") inside the "doSomething" function, you will get "undefined" for their values. That is because, again as pointed out above, the function is not aware that it belongs to an object so it does not know that the object has properties. The remedy is simple, simply append .bind(this) to the function when it is tied to the event as in:

  1. $(this.currentLinkID).observe('click'this.doSomething.bind(this));  


A similar approach needs to be applied when using the prototype built-in Ajax object. If you want to tie your custom functions to the "onFailure", "onComplete" or "onSuccess" functions, you need to use the "bindAsEventListener" function:

  1. onSuccess: this.showContent.bindAsEventListener(this)  


"Bind" also needs to be used whenever you employ the "each" construct as described in Gotcha with Prototype.Bind and Arrays

Below is the full class:

  1. var sampleObject = Class.create();   
  2. sampleObject.prototype = {   
  3.     linkIDs: ['mainPageLink''cdmScreenLink''adminLink''helpLink'],   
  4.     statusMessage: '',   
  5.     currentLinkID: 'myLink',   
  6.     initialize: function() {   
  7.         this.statusMessage = 'Who Am I?';   
  8.   
  9.         $(this.currentLinkID).observe('click'this.doSomething.bind(this));   
  10.     },   
  11.     doSomething: function() {   
  12.         alert(this.statusMessage);   
  13.   
  14.         new Ajax.Request(   
  15.             $(this.currentLinkID).href,   
  16.             {   
  17.             method: 'get',   
  18.             onSuccess: this.processContent.bindAsEventListener(this),   
  19.             evalScripts: true  
  20.             }   
  21.         );   
  22.     },   
  23.     processContent: function(request) {   
  24.     }   
  25. }   
  26.   
  27. Event.observe(window, 'load'function() {   
  28.     var sampleObjectInstance = new sampleObject();   
  29. });  


To call the functions of the sampleObject from outside you would simply do:

  1. sampleObjectInstance.doSomething();  

While you can access it's properties with the syntax:

  1. alert(sampleObjectInstance.statusMessage);  


That concludes the basic guide to using object oriented programming with Prototype.

Monday, March 03, 2008 10:10:37 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
AJAX | Javascript | Programming
# Thursday, February 28, 2008

Over my course of .NET development, I have compiled a list of essential free tools for .NET applications. This is not a the alpha or the omega of tools, just a short list that I feel is essential.

  1. SharpDevelop

    http://www.icsharpcode.net/OpenSource/SD/Download
    An open source IDE for .NET. Check out the full feature tour.


  2. Visual Web Developer Express Edition

    http://www.microsoft.com/express/vwd
    Stripped down version of Visual Studio that allows you to write .NET web applications.


  3. TortoiseSVN

    http://tortoisesvn.net/downloads
    There is no better Subversion client for Windows. You need this if you are going to use VisualSVN with Visual Studio.


  4. NAnt

    http://nant.sourceforge.net
    .NET based automation tool that has many built in tasks but could be extended with custom code written in any .NET language.


  5. Snippet Compiler

    http://www.sliver.com/dotnet/SnippetCompiler
    Snippet compiler is a small tool to write and execute small chunks of .NET code without creating a Visual Studio project.


  6. .NET Reflector

    http://www.aisto.com/roeder/dotnet
    Reflector is the class browser, explorer, analyzer and documentation viewer for .NET. Reflector allows to easily view, navigate, search, decompile and analyze .NET assemblies in C#, Visual Basic and IL.


  7. Microsoft SQL Server Management Studio Express

    http://www.microsoft.com/downloads/details.aspx?FamilyID=c243a5ae-4bd1-4e3d-94b8-5a0f62bf7796&displaylang=en
    Tool for database administration and development from Microsoft


  8. Quest Comparison Suite for SQL Server

    http://www.quest.com/Comparison-Suite-for-SQL-Server
    Compare and synchronize database schema and data


  9. XYPlorer

    http://www.xyplorer.com
    Awesome file manager. The older version is completely free.


  10. Convert C# to VB.NET

    http://labs.developerfusion.co.uk/convert/csharp-to-vb.aspx
  11. NAnt Add-In

    http://www.netlogics.ch/devcenter/display/NLC/NAntAddin
    Visual Studio add-in for NAnt integration


  12. NUnit Add-In

    http://www.netlogics.ch/devcenter/display/NLC/NUnitAddin
    Visual Studio add-in for NUnit integration
Thursday, February 28, 2008 2:53:42 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Microsoft | Programming | Visual Studio
# Monday, February 25, 2008

At a fundamental level it's important to understand how JavaScript timers work. Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions that we have access to with which to construct and manipulate timers.

  • var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
  • var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
  • clearInterval(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.

In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution. This is best demonstrated with a diagram, like in the following:


(Click to view full size diagram)

There's a lot of information in this figure to digest but understanding it completely will give you a better realization of how asynchronous JavaScript execution works. This diagram is one dimensional: vertically we have the (wall clock) time, in milliseconds. The blue boxes represent portions of JavaScript being executed. For example the first block of JavaScript executes for approximately 18ms, the mouse click block for approximately 11ms, and so on.

Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later (how this queueing actually occurs surely varies from browser-to-browser, so consider this to be a simplification).

To start with, within the first block of JavaScript, two timers are initiated: a 10ms setTimeout and a 10ms setInterval. Due to where and when the timer was started it actually fires before we actually complete the first block of code. Note, however, that it does not execute immediately (it is incapable of doing that, because of the threading). Instead that delayed function is queued in order to be executed at the next available moment.

Additionally, within this first JavaScript block we see a mouse click occur. The JavaScript callbacks associated with this asynchronous event (we never know when a user may perform an action, thus it's consider to be asynchronous) are unable to be executed immediately thus, like the initial timer, it is queued to be executed later.

After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? In this case both a mouse click handler and a timer callback are waiting. The browser then picks one (the mouse click callback) and executes it immediately. The timer will wait until the next possible time, in order to execute.

Note that while mouse click handler is executing the first interval callback executes. As with the timer its handler is queued for later execution. However, note that when the interval is fired again (when the timer handler is executing) this time that handler execution is dropped. If you were to queue up all interval callbacks when a large block of code is executing the result would be a bunch of intervals executing with no delay between them, upon completion. Instead browsers tend to simply wait until no more interval handlers are queued (for the interval in question) before queuing more.

We can, in fact, see that this is the case when a third interval callback fires while the interval, itself, is executing. This shows us an important fact: Intervals don't care about what is currently executing, they will queue indiscriminately, even if it means that the time between callbacks will be sacrificed.

Finally, after the second interval callback is finished executing, we can see that there's nothing left for the JavaScript engine to execute. This means that the browser now waits for a new asynchronous event to occur. We get this at the 50ms mark when the interval fires again. This time, however, there is nothing blocking its execution, so it fires immediately.

Let's take a look at an example to better illustrate the differences between setTimeout and setInterval.

  setTimeout(function(){
    /* Some long block of code... */
    setTimeout(arguments.callee, 10);
  }, 10);
 
  setInterval(function(){
    /* Some long block of code... */
  }, 10);

These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.

There's a lot that we've learned here, let's recap:

  • JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
  • setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
  • If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
  • Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

All of this is incredibly important knowledge to build off of. Knowing how a JavaScript engine works, especially with the large number of asynchronous events that typically occur, makes for a great foundation when building an advanced piece of application code.

Monday, February 25, 2008 5:01:18 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Javascript | Programming
# Wednesday, February 13, 2008

You see it in Google search results and a lot of other sites that have good search functionality. When you perform a search, your words or phrases are highlighted in the search results making it easy for you to find the most relevant content.

Today I’m going to show you a simple way to add this to your website or blog so your users can find what they need in style. I think that this kind of thing should be implemented more often for how easy it is to implement.

Here we go!

The JavaScript code:

  1. function highlightOnLoad() {  
  2.   // Get search string  
  3.   if (/s\=/.test(window.location.search)) {  
  4.     var searchString = getSearchString();  
  5.     // Starting node, parent to all nodes you want to search  
  6.     var textContainerNode = document.getElementById("content");  
  7.     // The regex is the secret, it prevents text within tag declarations to be affected

  8.     var regex = new RegExp(">([^<]*)?("+searchString+")([^>]*)?<","ig");  
  9.     highlightTextNodes(textContainerNode, regex);  
  10.   }  
  11. }  
  12. // Pull the search string out of the URL  
  13. function getSearchString() {  
  14.   // Return sanitized search string if it exists  
  15.   var rawSearchString = window.location.search.replace(/[a-zA-Z0-9\?\&\=\%\#]+s\=(\w+)(\&.*)?/,"$1");  
  16.   // Replace '+' with '|' for regex  
  17.   return rawSearchString.replace(/\+/g,"\|");  
  18. }  
  19. function highlightTextNodes(element, regex) {  
  20.   var tempinnerHTML = element.innerHTML;  
  21.   // Do regex replace  
  22.   element.innerHTML = tempinnerHTML.replace(regex,">$1<span class='highlighted'>$2</span>$3<");  
  23. }  
  24. // Call this onload, I recommend using the function defined 
    // at: http://untruths.org/technology/javascript-windowonload/  

  25. addOnLoad(highlightOnLoad()); 

Now, the CSS:

  1. span.highlighted {  
  2.   background-color#161616;  
  3.   font-weightbold;  

Code explanation

First, the highlightOnLoad function checks window.location.search to see if we need to be running any of this stuff, then calls getSearchString to get a sanitized search string so that nothing funky can happen if, say, the user searches for ‘<script>’. You should really be sanitizing all search inputs at least on the back-end anyway.

Then, the highlightTextNodes function uses a regex replace on our textContainerNode’s innerHTML. The regex verifies that the text is between a > and a < (and not the other way around). Actually nice and simple!

Caveats

This may end up being a bit slow if you are doing this on a LOT of text, but for my blog text, it seems quite snappy to me. Also, the CSS does not bold text inside links, but the background color is there to make it obvious.

Wednesday, February 13, 2008 5:06:52 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Javascript | Programming
# Tuesday, February 12, 2008

There are at least 5 ways to return data from one table which is not in another table. Two of these are SQL Server 2005 and greater only. This is a post mostly for beginners but hopefully everyone will get something out of it.

Here are the 5 different ways

NOT IN
NOT EXISTS
OUTER JOIN
OUTER APPLY (2005+)
EXCEPT (2005+)

Let's see how this all works
First create these two tables with the Celko approved naming convention.

 

CREATE TABLE #testnulls (ID INT)

INSERT INTO #testnulls VALUES (1)

INSERT INTO #testnulls VALUES (2)

INSERT INTO #testnulls VALUES (null)

 

CREATE TABLE #testjoin (ID INT)

INSERT INTO #testjoin VALUES (1)

INSERT INTO #testjoin VALUES (3)

NOT IN
Run the following Code

 

SELECT * FROM #testjoin WHERE ID NOT IN(SELECT ID FROM #testnulls)

What happened? Nothing gets returned! The reason is because the subquery returns a NULL and you can't compare a NULL to anything

Now run this

SELECT * FROM #testjoin

WHERE ID NOT IN(SELECT ID FROM #testnulls WHERE ID IS NOT NULL)

That worked because we eliminated the NULL values in the subquery

This also works

SELECT * FROM #testjoin j

WHERE j.ID NOT IN(SELECT ID FROM #testnulls n WHERE n.ID = j.ID)

 


NOT EXISTS
NOT EXISTS doesn't have the problem that NOT IN has. Run the following code

 

SELECT * FROM #testjoin j

WHERE NOT EXISTS (SELECT 1

FROM #testnulls n

WHERE n.ID = j.ID)

Everything worked as expected


LEFT and RIGHT JOIN
Plain vanilla LEFT and RIGHT JOINS

 

SELECT j.* FROM #testjoin j

LEFT OUTER JOIN #testnulls n ON n.ID = j.ID

WHERE n.ID IS NULL

With a RIGHT Join you just switch the tables around

SELECT j.* FROM #testnulls n

RIGHT OUTER JOIN #testjoin j ON n.ID = j.ID

WHERE n.ID IS NULL

 

And we can also do a full outer join

SELECT j.* FROM #testnulls n

FULL OUTER JOIN #testjoin j ON n.ID = j.ID

WHERE n.ID IS NULL

AND j.ID IS NOT NULL


You might wonder why we have LEFT and RIGHT Joins, here is why:
<AttemptToBeFunny>LEFT joins are for people who tend to vote for the democrats, RIGHT joins are for people who tend to vote for Republicans. FULL Joins are for independents/undecided people. </AttemptToBeFunny>

You can be real silly and do a subquery LEFT join
 

SELECT j.* FROM #testjoin j

LEFT OUTER JOIN (SELECT ID FROM #testnulls ) n ON n.ID = j.ID

WHERE n.ID IS NULL

 

Now let's talk about SQL 2005 and up

OUTER APPLY (SQL 2005 +)
OUTER APPLY is something that got added to SQL 2005

SELECT j.* FROM #testjoin j

OUTER APPLY

(SELECT id FROM #testnulls n

WHERE n.ID = j.ID) a

WHERE a.ID IS NULL

 

EXCEPT(SQL 2005 +)
EXCEPT is something that got added to SQL 2005. It basically returns everything from the top table which is not in the bottom table

 

SELECT * FROM #testjoin

EXCEPT

SELECT * FROM #testnulls


I am also mentioning INTERSECT since some people might not have seen it before. INTERSECT returns what ever is in both tables(like a regular join)

 

SELECT * FROM #testjoin

INTERSECT

SELECT * FROM #testnulls

 

So there you have it, most likely you already know all these types of joins. If you learned something from this post that is a good thing also.

Tuesday, February 12, 2008 5:05:36 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [1] - Trackback
Programming | SQL
# Sunday, February 10, 2008

It was all going so smoothly. Jason Whittington, Mark Smith and I were teaching the big DevelopMentor event here in Los Angeles (Guerrilla.NET) when my presentation on the ThreadPool took a nose dive. It started with a great joke involving Wilson (the volleyball from Cast Away).

Wilson and I built an application to compute a multiplication table where each computation was (artificially) slow. To speed it up we threw it at the thread pool using delegate.BeginInvoke. We figured that the ThreadPool would allocate 25 or so threads and the table would display quickly. Here's the expected output - pretty much the same thing we've seen since about .NET 1.0:

    

Each color represents the thread that did that computation.

For the last 7 years, the behavior has been that as the ThreadPool was overloaded, it would steadily start up new threads at the rate of one every 500 milliseconds until it hits its upper limit (typically). Using Performance Monitor (perfmon) we can watch the thread pool adding threads. It usually looks something like this:

    

Much to our surprise we saw completely different behavior. The thread pool added the first 15 or so threads quickly (as expected) but then stalled. New threads were not created every 500ms, instead they were added at increasingly long intervals. My demo took almost twice as long to run as it had the last time I did this demo a few months ago.

Jason, Mark, and I took this code, ported it back to .NET 1.1 and ran it side-by-side with .NET 3.5 and here's what we saw (blue = 3.5, red = 1.1):

    

As of .NET 3.5 the upper limit of the ThreadPool was increased: Knew that.

But, it appears that v3.5 of the CLR changes the policy for adding threads to the thread pool. Rather than adding threads regularly when under load the thread pool uses a logarithmic backoff. My colleague Jason Whittington remarked that this behavior looked similar to the behavior of the thread pool in "Rotor" (the shared-source version of the CLR). We speculated that this backoff algorithm makes sense given the new 250-thread per CPU maximum - it would take a long time to reach that if the runtime waits longer and longer to start a new thread. The 250-thread limits makes it less likely that your application will deadlock the thread pool, and the exponential backoff algorithm keeps the thread pool from creating too many threads too quickly.

Why should you care? Usually you won't, but it could have dramatic impact if you count on that behavior. For example, in our contrived case, .NET 1.1 ran about twice as fast as .NET 3.5 ( ! ):

    

Here's the program and source code (trimmed down to run in both .NET 1.1 and 3.5).

    Math.zip (6.38 KB)

Sunday, February 10, 2008 5:03:47 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [3] - Trackback
.Net | Programming | Visual Studio
# Tuesday, February 05, 2008

Working as a team against a common database schema can be a real challenge. Some teams prefer to have their local code connect to a centralized database, but this approach can create many headaches. If I make a schema change to a shared database, but am not ready to check in my code, that can break the site for another developer. For a project like Subtext, it is just not feasible to have a central database.

Instead, I prefer to work on a local copy of the database and propagate changes via versioned change scripts. That way, when I check in my code, I can let others know which scripts to run on their local database when they get latest source code. Of course this can be also be a big challenge as the number of scripts starts to grow and developers are stuck bookkeeping which scripts they have run and which they haven’t.

That is why I always recommend to my teams that we script schema and data changes in an idempotent manner whenever possible. That way, it is much easier to simply batch updates together in a single file (per release for example) and a developer simply runs that single script any time an update is made.

As an example, suppose we have a Customer table and we need to add a column for the customer’s favorite color. I would script it like so:

IF NOT EXISTS 
(
    SELECT * FROM [information_schema].[columns] 
    WHERE   table_name = 'Customer' 
    AND table_schema = 'dbo'
    AND column_name = 'FavoriteColorId'
)
BEGIN
    ALTER TABLE [dbo].[Customer]
    ADD FavoriteColorId int
END

This script basically checks for the existence of the FavoriteColorId column on the table Customer and if it doesn’t exist, it adds it. You can run this script a million times, and it will only make the schema change once.

You’ll notice that I didn’t query against the system tables, instead choosing to lookup the information in an INFORMATION_SCHEMA view named Columns. This is the Microsoft recommendation as they reserve the right to change the system tables at any time. The information views are part of the SQL-92 standard, so they are not likely to change.

There are 20 schema views in all, listed below with their purpose (aggregated from SQL Books). Note that in all cases, only data accessible to the user executing the query against the information_schema views is returned.

Name Returns
CHECK_CONSTRAINTS Check Constraints
COLUMN_DOMAIN_USAGE Every column that has a user-defined data type.
COLUMN_PRIVILEGES Every column with a privilege granted to or by the current user in the current database.
COLUMNS Lists every column in the system
CONSTRAINT_COLUMN_USAGE Every column that has a constraint defined on it.
CONSTRAINT_TABLE_USAGE Every table that has a constraint defined on it.
DOMAIN_CONSTRAINTS Every user-defined data type with a rule bound to it.
DOMAINS Every user-defined data type.
KEY_COLUMN_USAGE Every column that is constrained as a key
PARAMETERS Every parameter for every user-defined function or stored procedure in the datbase. For functions this returns one row with return value information.
REFERENTIAL_CONSTRAINTS Every foreign constraint in the system.
ROUTINE_COLUMNS Every column returned by table-valued functions.
ROUTINES Every stored procedure and function in the database.
SCHEMATA Every database in the system.
TABLE_CONSTRAINTS Every table constraint.
TABLE_PRIVILEGES Every table privilege granted to or by the current user.
TABLES Every table in the system.
VIEW_COLUMN_USAGE Every column used in a view definition.
VIEW_TABLE_USAGE Every table used in a view definition.
VIEWS Every View

When selecting rows from these views, the table must be prefixed with information_schema as in SELECT * FROM information_schema.tables.

Please note that the information schema views are based on a SQL-92 standard so some of the terms used in these views are different than the terms in Microsoft SQL Server. For example, in the example above, I set table_schema = 'dbo'. The term schema refers to the owner of the database object.

Here is another code example in which I add a constraint to the Customer table.

IF NOT EXISTS(
    SELECT * 
    FROM [information_schema].[referential_constraints] 
    WHERE constraint_name = 'FK_Customer_Color' 
      AND constraint_schema = 'dbo'
)
BEGIN
  ALTER TABLE dbo.Customer WITH NOCHECK 
  ADD CONSTRAINT
  FK_Customer_Color FOREIGN KEY
  (
    FavoriteColorId
  ) REFERENCES dbo.Color
  (
    Id
  )
END

I generally don’t go to all this trouble for stored procedures, user defined functions, and views. In those cases I will use Enterprise manager generate a full drop and create script. When a stored procedure is dropped and re-created, you don’t lose data as you would if you dropped and re-created a table that contained some data.

With this approach in hand, I can run an update script with new schema changes confident that I any changes in the script that I have already applied will not be applied again. The same approach works for lookup data as well. Simply check for the data’s existence before inserting the data. It is a little bit more work up front, but it is worth the trouble and schema changes happen less frequently than code or stored procedure changes.

Tuesday, February 05, 2008 11:57:38 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | SQL

Some developers love working with relational databases, and other developers can't stand to touch them. Either way - if your application uses a database, you have to treat the database with some respect. The database is as much a part of an application as the code and the models inside the software.

Here are three rules I've learned to live by over the years of working with relational databases.

1. Never use a shared database server for development work.

Fossil!The convenience of a shared database is tempting. All developers point their workstations to a single database server where they can test and make schema changes. The shared server functions as an authoritative source for the database schema, and schema changes appear immediately to all team members. The shared database also serves as a central repository for test data.

Like many conveniences in software development, a shared database is a tar pit waiting to fossilize a project. Developers overwrite each other's changes. The changes I make on the server break the code on your development machine. Remote development is slow and difficult.

Avoid using a shared database at all costs, as they ultimately waste time and help produce bugs.

2. Always Have a Single, Authoritative Source For Your Schema

Ideally, this single source will be your source control repository (see rule #3). Consider the following conversation:

Developer 1: It's time to push the app into testing. Do we copy the database from Jack's machine, or Jill's machine?

Developer 2: Ummmmmmmm, I don't remember which one is up to date.

Developer 1: We're screwed.

Everyone should know where the official schema resides, and have a frictionless experience in getting a fresh database setup. I should be able to walk up to a computer, get the latest from source control, build, and run a simple tool to setup the database (in many scenarios, the build process can even setup a database if none exists, so the process is one step shorter).

How you put your database into source control depends on your situation and preferences. Any decent O/R mapping tool should be able to create a database given the mappings you've defined in a project. You can also script out the database as a set of one or more files full of SQL DDL commands. I generally prefer to keep database views and programmatic features (including functions, triggers, and stored procedures) as separate files - but more on this in a later post.

There are plenty of tools to help. Leon Bambrick has a long list (albeit one year old list) of tools and articles that can help, while Jeff Atwood gushes over the virtues of Visual Studio for Database Professionals.

3. Always Version Your Database

There are many ways to version databases, but the common goal is to propagate changes from development, to test, and ultimately to production in a controlled and consistent manner. A second goal is to have the ability to recreate a database at any point in time. This second goal is particularly important if you are shipping software to clients. If someone finds a bug in build 20070612.1 of your application, you must be able to recreate the application as it appeared in that build - database and all.

In a future post, I'll describe an approach I've used for database versioning that has worked well for many years of commercial development.

In the meantime, if you are looking for more database rule, then Adam Cogan and SSW maintain an excellent list.

Tuesday, February 05, 2008 11:35:24 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | SQL
# Sunday, February 03, 2008

I'm sure everyone's tired of hearing about C# 3.0 features like lambda expressions, extension methods, anonymous types and so on.  Before you fall in love with the new features, there are a few oldies-but-goodies that revolve around the "?" character.  I use a couple of these to stump interviewees who proclaim themselves to be C# experts.  These question marks can provide a much cleaner, terser syntax for some fairly common C# usage patterns.

Conditional operator

This one can be easy to abuse, but it provides a nice terseness to code that has conditional assignments:

if (hoursTraveled > 0)
    speed = distanceInMiles / hoursTraveled;
else
    speed = 0;

I'm trying to calculate speed, but clearly I don't want to get DivideByZeroException.  Sometimes these types of assignments can add up, so I like to condense them down with the C# conditional operator:

speed = hoursTraveled > 0 ? distanceInMiles / hoursTraveled : 0;

Now the conditional assignment can be written on a single line.

I don't see this feature used very often, so there is a tradeoff in familiarity.  If the conditional or assignment statements grow too large, it can start to hurt readability, so just use your best judgement on this one.

Nullable types

The release of the .NET Framework 2.0 brought along a little struct type that solved a whole heap of problems.  Value types (structs) can be used to represent types that don't care about referential identity.  For example, if I have the number 2, and you have the number 2, they're the same number no matter how many times we create it.

Value types have another interesting aspect, they can never have a null value.  The details behind this are exciting if you like things Jeffrey Richter style, full of heap and stack knowledge, but in the end you just need to know that C# structs can never be null.  This line does not compile:

int i = null;

But not every system in the world that deals with "int" recognizes this rule.  Databases and XML schemas are two examples where "int" values can be null.  To handle the impedance mismatch of real-world nulls and CLR-land value types, the Nullable<T> generic value type was introduced.  By declaring a variable to be Nullable<int>, I can now do this:

Nullable<int> i;
i = null;

Assert.That(i.HasValue, Is.False);

i = 3;

Assert.That(i.HasValue, Is.True);
Assert.That(i.Value, Is.EqualTo(3));
Assert.That(i, Is.EqualTo(3));

Note that I have no problems assigning int values to the Nullable<int> type, as the appropriate cast operators have been defined.  Declaring a nullable type is fairly ugly using the full generic notation, so C# has a nice shortcut:

int? i;
i = null;

There's our friend the question mark.  It's telling us "I think this variable is an int, but I'm not sure?".  This is just another compiler trick C# uses, just like extension methods.  At compile time, "int?" is replaced with "Nullable<int>", so it's really just a shorthand way of expressing nullable types.

Before nullable types, I had to use a bunch of dirty tricks to represent nulls in my entities, usually with magic numbers and values like "Double.NaN" or "DateTime.MinValue".  Nullable types let me bridge the gap between the nullable and non-nullable worlds.

Null coalescing operator

This is the one I love to stump the self-proclaimed experts with.  I draw this on the whiteboard:

??

And ask them, "what does this operator do in C#?"  Usually I get the crickets, but the special few can tell me about the null coalescing operator.  The null coalescing operator is very similar to the conditional operator, but with the conditional built-in.  I find myself doing this quite a lot with nulls:

if (category.Description == null)
    output = "<Empty>";
else
    output = category.Description;

I have a value that could potentially be null, in this case the description of a category, but I need to output that value to a friendly format.  Unfortunately, nulls aren't always too friendly to end-users.  Let's try the conditional operator to see how that cleans things up:

output = category.Description != null ? category.Description : "<Empty>";

But these conditionals can get ugly, so I can use the "??" operator to provide an even terser syntax:

output = category.Description ?? "<Empty>";

All of these representations are equivalent, but I like the short and sweet syntax the "??" operator provides.  Someone not familiar with this operator might not have any clue what the code does, so there is some level of risk involved.

But I generally don't like to let a lack of knowledge with a built-in language feature deter me from using it, especially if it can provide a much cleaner syntax.

And as always...

If the syntax and usage these little question marks provide don't provide better readability (solubility?), then don't put them in.  These features are there to help, not to satisfy technical fetishes.  As always, keep in mind that your end goal is better readability and better maintainability, not a checklist of features used.

Sunday, February 03, 2008 11:29:34 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | Visual Studio
# Thursday, January 24, 2008

Introduction:
Ajax application performance largely depends on the performance of JavaScript execution and browser DOM operations. I've heard various people saying various things about Ajax performance. Some people say JavaScript is just too slow. Some people say that the problem is not JavaScript but rather Browser DOM being too slow. Some people would then argue that browser DOM operations are fine. The problem is Internet Explorer that is unbelievably slow. 
 
What is the reality? Having heard enough but haven’t seen enough data to clearly justify one argument against the other ones, I decided to take some time and do some study in this area.

The Study:
Using the work produced by Robert Buffone at http://www.rockstarapps.com and a 2GB RAM/1.66GHz Dual CPU Windows XP machine, a JavaScript performance study is conducted. The results are shown in Appendix 1:
1.      Vertically, in each column, Appendix 1 shows how a particular operation performs in comparison to other operations on the same browser. Using an empty function call as the “base” for comparison, Appendix 1 shows the comparative percentage of time that other operations consume relative to that of the base operation. Note that for each browser, the time that most operations take is comparable to that of an empty function call. However, certain operations are significantly more expensive, some times even a few million percent more expensive, than the base empty function call;
2.      Horizontally, on each row, Appendix 1 shows how different browsers perform with regard to the same operation. Safari typically outperforms FireFox and FireFox outperforms Internet Explorer. However, there are exceptions that Internet Explorer outperforms other browsers. 

What Are The Ajax Performance Issues?
What are noteworthy from the study are:
a)      JavaScript performance can be greatly enhanced via better implementations, without API change or new standard. In the above comparison, Safari generally beats Internet Explorer by a few hundred percent or even more in terms of performance, which is fairly dramatic.
b)      Internet Explorer really needs to enhance its JavaScript runtime performance to make it on par with other browsers. The significantly lower performance and the significant market share of Internet Explorer together create a major challenge for Ajax performance.
c)      That being said, other browsers also have performance bottlenecks.

More specifically, here is a list of Ajax performance issues:
1.    Array performance on all browsers in general
2.    HTML DOM performance in general
3.    Calculating Computed Box Model and Style
4.    FireFox: “eval”, Object Creation and “in” Operation
5.    “String” Manipulation Performance on IE
6.    Safari: “pop” Operation Performance

1.    “Array” Is Slow on All Browsers
Array-related operations are expensive for all browsers. Comparing to other operations, the same browser takes considerable more time for array-related operations. The differences can be a few orders of magnitude some times. Specifically:
1.    For IE7: “pop”, “push”, “shift”, “join” etc are all very expensive that can take ten times or even a few hundred times longer to complete than other operations;
2.    For FireFox: “pop” and “push” operations perform fairly well in comparison to other operations (“pop” and “push” operations cost 160% of the base operation on FireFox. On IE, they cost 532% and 3523% of the base operation respectively). “shift” and “join” are very expensive. The operation “creating an empty array using ‘new Array()’ constructor” costs 662% of the base operation while this number is only 119% and 145% on IE and Safari. This is related to the issue that it is very expensive for FireFox to create new objects. Other browsers do not seem to have this problem.
3.    For Safari, “pop”, “shift” and “join” are expensive operations.

2.  HTML DOM Operation Performance in General
All HTML DOM related JavaScript calls are significantly more expensive than most other operations across all browsers. On Safari, DOM calls cost from a few hundred percent to a few thousand percent of the base operations. On Internet Explorer, the cost can be as higher as tens of thousands of percentage. Given that DOM operation is essential to almost every browser-based application, improvement in this area can significantly broaden the applicability of Ajax applications.

3. Calculating Computed Box Model and Computed Style
Getting computed box model calculations out of IE is not for the faint of optimization. According to a post by Alex Russell at Dojo Foundation (see reference http://alex.dojotoolkit.org/?p=644),  when they profiled Dojo widgets for Dojo 1.0, they noted very quickly that getting box-model data out of the browser for any element is hugely costly on every browser, but on IE the cost was not just big… it was enormous. Our best guess right now is that the properties on the currentStyle property are re-calculated when they’re requested from script and not cached in the bound object when layout happens. The resulting performance penalty requires that developers nearly never manage layout in code, severely constraining the layouts which are attempted by toolkits like Dojo.

Why Is This Important?
Current browsers provide limited support for layout management. A lot web sites use “table” for managing layout, while some others use CSS for doing layout. Though both table and CSS are capable of serving the purpose of layout, layout support is not a first class citizen. There is not out-of-box support for common layout managers (such as docking, border layout). There is no layout object and there is no programmatic API for layout management. As a result, providing better layout management has been a task undertaken by JavaScript toolkits. Calculating the computed box model and style is essential for JavaScript toolkits to be able to manage layout.

4. FireFox Specific Performance Issues
Comparing to other browsers, FireFox performs very poorly for the following operations:
1.    “eval” of object or function: These two operations take Safari 9.4ns and 22.7ns, IE7 172ns and 94ns. But they take FireFox 546ns and 749ns.
2.    Object creation: Operations like “var myObject = new MyObject (17, 250);” and “var slowCar = {m_tireSize:17, m_maxSpeed:250};” are very expensive on FireFox comparing to other browsers. The differences between them are: 11.7ns and 8.6ns for IE7, 3.2ns and 2.4ns for Safari, 23.4ns and 23.4ns for FireFox which are almost 10 times more expensive than Safari and a few times more expensive than IE7.
3.    “in” operation: Operation “looping an array through ‘in’” takes IE 10.3ns and Safari 7.8ns, but 62.8ns for FireFox. Again, a difference of almost 10 times.

5. IE Specific Performance Issues
IE performs worse than FireFox and Safari in general. Beyond the areas that all browsers have problems, String manipulation deserves particular attention for IE.

String compares and concatenation on IE6 are super bad. According to Robert Buffone, “I left out IE 6 for the exercise because it is so bad on everything it would just make every JavaScript coder extremely mad”.

IE7 has made progress on this. But it still lags behind by a few hundred percent comparing to other browsers.

Why is this important?
1.    Every application involves String manipulation. Part of the appeal of Ajax is the benefit of leveraging client side processing power, which naturally leads to a lot more String manipulations on the client side;
2.    As pointed out by reference (http://alex.dojotoolkit.org/?p=644), most non-trivial blocks of JavaScript code today rely on innerHTML to bootstrap some new chunk of DOM in response to user action due in large part to the cross-browser speed and size advantages of innerHTML vs. raw DOM methods for equivalent DOM structures. Because building innerHTML is essentially String manipulation, the performance of string manipulation heavily influences the performance of Ajax applications.


6. Safari Specific Performance Issues
Safari in general performs really well comparing to other browsers. The only operation that Safari performs significantly worse than other browsers is “pop” method. In summary, if every browser can match Safari’s performance, it would be a significant step forward for web development.

Where Do We Go From Here?
Obviously, we would like to see browser vendors take a serious look into the following issues and put them on their roadmap:
1.    In all major browsers, performance with Array and HTML DOM needs improvement in general.
2.    Browsers need to provide API support for Computed Box Model and Style;
3.    FireFox needs to improve performance of “eval”, object creation and “in” operation
4.    Internet Explorer needs to improve performance in general to be at least on par with other browsers. Beyond that, “String” manipulation on IE needs continued improvements;
5.    Safari: “pop” operation performance needs improvement
6.    Just-in-time (JIT) compiler: This maybe a bigger task than an incremental fix of some existing features, however, it is worthy of every penny.  JIT will not only fix the String manipulation issue, it will enable JavaScript to truly shine in matching the performance of native applications. The amount of client side logic (aka, JavaScript code) needs to grow in order to accommodate the growth of application complexity, for which JavaScript runtime performance problem can be a major bottleneck.

But how can we get browser vendors to listen to us?

First of all, help make some noise! The community needs to come together and your participation is crucial in making something happen.

Secondly, let’s look around and get some coordinated acts together. At OpenAjax Alliance (http://www.openajax.org), we are starting a task force called “Runtime Advocacy Task Force”. At the OpenAjax 2007 September Member Meeting, the members of OpenAjax Alliance discussed the challenges for future Ajax growth and adoption, in particular, issues directly related to the various Ajax runtime environments. The collective wisdom was that OpenAjax Alliance should do something in this area to help creating a better Ajax eco-system. The work is still in its early stage, but watch for progress over the next month or so.

Appendix 1: Browser Performance Study and Comparison

Testing setup:

·         Windows XP SP2,  DELL Latitude D820,  2GB RAM, 1.66GHz Dual CPU

·         IE 7.0.5730.11

·         FireFox 2.0.0.11

·         Safari 3.0.2 (522.13.1)

·         Application: http://www.rockstarapps.com/samples/performance/

 

Internet Explorer 7

      FireFox

     Safari

Description

Time (ns)

% of base

Time (ns)

% of base

Time (ns)

% of base

Normal Empty function call (Base Operation)

4.7

100%

3.9

100%

1.6

100%

Basic Function Calls

 

 

 

 

 

 

Function call using function.call(this)

5.5

116%

2.4

60%

1.6

100%

Normal Empty function using apply

5.5

117%

7.0

179%

2.4

152%

Normal Empty function using apply with 3 parameters

7.0

149%

7.1

181%

2.4

152%

Eval a function

172.0

3660%

546.0

14000%

9.4

603%

Eval an object

94.0

2000%

749.0

19205%

22.7

1461%

Basic Operations

 

 

 

 

 

 

Access Properties through a getter

13.3

282%

6.3

160%

5.5

352%

Access Properties directly

4.7

100%

3.2

81%

2.4

152%

 

 

 

 

 

 

 

Simple string concatenation

4.7

100%

2.3

59%

1.6

100%

Simple string compare

3.9

83%

2.4

60%

0.8

48%

Change string to upper case

11.7

249%

3.9

100%

4.7

303%

Replace string reg expression

12.5

266%

7.1

181%

9.4

603%

String concat with integer

7.1

150%

4.7

119%

2.4

152%

String concat with float

6.3

133%

4.7

121%

2.4

152%

Index of Bob in string, not found, length = 71

6.3

133%

6.3

160%

2.4

152%

Match of Bob in string, not found, length = 71

14.9

316%

25.0

640%

3.9

252%

charAt(10) in string

11.7

249%

6.3

160%

3.1

200%

 

 

 

 

 

 

 

Create object constructor initialized

11.7

249%

23.4

600%

3.2

203%

create simple object

8.6

182%

23.4

600%

2.4

152%

 

 

0%

 

 

 

 

Variable declaration

4.0

84%

2.3

59%

0.8

48%

Multiple variable declaration, multiple var

3.9

83%

2.4

60%

2.4

152%

Multiple variable declaration single var

3.9

83%

2.4

60%

1.6

100%

Variable declaration set to null

3.9

83%

2.4

60%

1.6

100%

 

 

0%

 

 

 

 

Variable assignment++

4.7

100%

5.5

140%

1.6

103%

Variable assignment + 1

5.5

116%

7.1

181%

1.6

100%

 

 

 

 

 

 

 

Four levels of property access

5.5

116%

5.5

140%

1.6

100%

Three levels of property access

4.7

100%

4.7

121%

2.4

152%

Two levels of property access

4.7

100%

4.7

119%

1.6

100%

One level of property access

3.9

83%

4.7

121%

1.6

103%

 

 

0%

 

 

 

 

Using the typeof function

3.9

83%

4.7

119%

1.6

100%

Array Operations

 

 

 

 

 

 

Array access

7.1

150%

7.0

179%

1.6

100%

Array index value change

3.9

83%

4.7

121%

1.6

103%

Empty Array index value change

8.6

183%

8.6

221%

6.3

403%

Empty Array add three values

10.2

216%

11.7

300%

3.1

200%

Empty Array with set size

11.0

233%

11.0

281%

3.2

203%

Empty Array using constructor

9.4

199%

25.8

662%

2.3

148%

 

 

 

 

 

 

 

Push element onto an Array

25.0

532%

6.3

160%

1.5

98%

Pop element of an Array

165.6

3523%

6.3

160%

249.7

16112%

Push element onto an Array

6.2

132%

7.1

181%

1.4

92%

Shift elements off the front of an Array

2030.0

43191%

5620.0

144103%

1250.0

80645%

Join the array into a string

125000

2659574%

47000

1205128%

16000

1032258%

Push element onto an Array

7.1

150%

7.0

179%

3.9

252%

Sorting of an Array

93.0

1979%

45.3

1162%

32.9

2119%

 

 

 

 

 

 

 

Math.max(7.25,7.30)

5.5

116%

4.7

121%

3.9

252%

Math.min(7.25,7.30)

5.5

117%

4.7

121%

3.2

203%

HTML DOM Operations

 

 

 

 

 

 

Change text using innerHTML

469.0

9979%

234.0

6000%

109.0

7032%

Create a text node on HTML Dom

1093.0

23255%

156.0

4000%

110.0

7097%

Change the class name of an element

422.0

8979%

47.0

1205%

109.0

7032%

 

 

 

 

 

 

 

getElementById

86.8

1846%

15.7

401%

3.9

252%

getElementsByTagName("div")

153.1

3257%

18.0

462%

5.5

352%

getElementsByTagName("spa")

142.2

3024%

18.8

481%

5.5

355%

getElementsByName

93.8

1995%

44.6

1142%

4.7

303%

 

 

 

 

 

 

 

placeDiv.getAttribute("id")

29.7

632%

46.8

1200%

5.5

352%

placeDiv.attributes["id"]

31.3

665%

225.0

5769%

6.3

403%

var atts = placeDiv.attributes; atts["id"].name

11.7

249%

18.8

482%

4.7

303%

var atts = placeDiv.attributes; atts.id.name

12.5

266%

18.8

482%

3.9

252%

Try/Catch

 

 

 

 

 

 

Function call using function.call(this)

7.1

150%

4.0

101%

2.4

152%

Try catch

7.1

150%

6.3

160%

5.5

352%

Try catch with throw

17.2

365%

7.8

200%

5.5

355%

Try catch finally

9.4

199%

7.8

200%

4.7

303%

Try catch finally with throw

16.5

350%

11.0

281%

6.3

403%

If statement and Date object

 

 

 

 

 

 

Create a date object

12.5

266%

10.2

260%

3.1

200%

Create a date object and call getDate()

28.1

598%

50.8

1303%

10.2

658%

 

 

 

 

 

 

 

The switch statement

4.7

99%

2.4

60%

2.4

152%

An if statement

4.0

84%

2.4

60%

2.4

152%

 

 

 

 

 

 

 

Simple if else

4.1

86%

2.2

56%

1.9

121%

turinary operator

3.9

83%

2.3

60%

2.0

131%

 

 

 

 

 

 

 

Compare of matching string ==

4.7

100%

7.1

181%

2.4

152%

Compare of matching string ===

4.7

100%

7.0

179%

2.4

152%

Compare of non-matching string

4.7

100%

3.9

100%

2.4

152%

 

 

 

 

 

 

 

Compare  TEST_INT == 5

4.1

86%

4.2

108%

1.7

111%

Compare  5 == 5

4.1

87%

2.0

52%

1.6

101%

Looping Performance Statistics

 

 

 

 

 

 

Loop through an array using in

10.3

219%

62.8

1610%

7.8

503%

Loop through an array using for (i++)

6.3

133%

10.6

273%

3.4

222%

Loop through an array using for (i < myArray.length)

6.2

133%

10.9

281%

3.1

201%

Loop through an array using for (i = 0; i < len; i++)

5.0

106%

4.7

120%

4.1

262%

Loop through an array using for (i = 0; i < len; i++)

5.3

113%

5.0

128%

4.1

262%

Loop through an array using while {i++}

5.3

113%

5.3

136%

4.7

302%

Loop through an array using while (i++ < len)

5.0

106%

5.0

128%

4.4

283%


Thursday, January 24, 2008 2:43:45 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
AJAX | Programming
# Wednesday, January 23, 2008

Redesigning a website can be a very involved process, and it is important to properly plan and consider the necessary factors that will make or break the redesign. Here is a quick look at 21 factors that you should be contemplated.

1. What is the goal of the redesign?

What do you hope to accomplish? It’s always important to have a clear understanding of your reasons and motivations as they should impact the decisions that you make along the way. Without knowing these goals the project will lack direction and you will likely wind up with a website that still doesn’t meet your needs.

2. Is this going to be just a minor upgrade or a complete overhaul?

A redesign could be anything from a minor facelift to an entirely new site. Obviously the time, effort, and cost involved will vary, but first you should determine what types of changes are required for you to meet your goals with the design. If a complete redesign is done you will also want to consider to what extent the new design should resemble the old design. If visitors are coming back to the site, chances are you will want them to notice the new design without feeling like they’ve never been to your site before.

3. What aspects of the current design are most effective?

Most likely there are some things about the current design that work very well, and these may be aspects that you would like to keep or incorporate into the new design. It’s a good idea to make a simple list of your likes and dislikes to help with decisions on the new design.

4. What aspects of the current design are not effective?

Building on point #3, if you are redesigning the site you are bound to want to get rid of some specific aspects of the website or the design. Are there some characteristics of the design that do not accurately portray your business to new visitors?

5. Who are your target users?

During any design process you never want to lose focus on the visitors. By knowing who you are targeting and how you can meet their needs, you will be on your way to building an effective website. What style of design are your users going to like?

6. How can the website be more user-friendly?

Improving the functionality and usability of a website is always a good thing. It’s pointless to spend time and money on a redesign that looks great but simply isn’t user-friendly.

7. Does the logo/branding need to be changed or updated?

Most likely the website will include some form of a logo or branding. Are these items still up-to-date and will they function effectively with a new design? If your logo is out-of-date and not attractive, a new design may not do much good if it is still using the same old logo.

8. Should the color scheme change or remain the same?

In point #2 I mentioned that most of the time you will want to keep the website at least looking familiar to repeat visitors. Using a similar color scheme is one of the best ways to accomplish this. A lot of times it can be a good idea to make some minor changes to the color scheme, such as changing shades of colors or adding a few new colors, just to give the site a fresh look.

9. What screen resolutions are visitors using?

It’s important to know how your visitors are going to be viewing the site. A program such as Google Analytics can easily give you this information. Obviously, a fixed-width design should take into consideration the typical screen resolutions of visitors.

10. What connection speed are visitors using?

Knowing the connection speed will help you to know what types of elements you can include in the design without causing hardships for the average visitor.

11. What should be the focal points of the design?

Every design is going to draw attention to certain parts of the page in one way or another. By knowing what you want to emphasize you will have more control over what gets attention from visitors. In a comment on a recent article, Caroline Middlebrook mentioned that in her redesign she used the area above blog posts to feature some select content, such as a free e-book that she has written. Obviously, in her case this is a focal point that she wants visitors to notice.

12. How can the navigation be made more effective?

Navigation is one of the most critical elements of a site’s usability. If a significant amount of content and/or pages have been added to the site since the last design, it is possible that navigation is no longer optimal. Before designing think about how visitors will want to move through the site, and make it as easy as possible for them.

13. What will visitors want from the website?

Meeting the needs of visitors is important to the success of any website. Will visitors be coming to the site looking for information? If so, make it easy to find the information and make it a prominent part of the design. Will they be coming to the site to find products? Will they be coming for some other reason? Anticipate what your visitors will want and do your best to give it to them.

14. How can increased user interaction be incorporated?

The most successful websites are able to get visitors involved in one way or another. Blogs are great for this purpose because they allow for comments and discussion. Other possibilities are forums, games, user-generated content, polls, quizzes, etc. By making the website more engaging to visitors you are more likely to get a high number of repeat visitors.

15. Who will be doing the maintenance/updates?

Will you be the one doing routine maintenance and updates? Will someone else be doing them? If multiple people will be using the website commenting the code becomes even more important. Code should always be kept as clean as possible, but when others will be doing work on the site has a bigger impact.

16. Is a content management system (CMS) needed?

Many website owners now prefer to use a CMS, such as WordPress, so that the site can easily be updated without requiring a designer. Depending on the amount and type of updates that are anticipated, a CMS may be a good, time-saving decision.

17. How can SEO be improved?

Any time a website is being designed, search engines should be considered. The current design may or may not be search engine-friendly, but the new one certainly should be. Should the current page titles be kept, or could they be done more effectively? How can internal linking be improved? Where can headers be used? This list could obviously go on for a while.

18. What keywords and phrases are being targeted?

Of course, keywords should be used in titles, headers, anchor text, alt tags, etc. Designing a website without knowing what words and phrases you are targeting means that you are most likely targeting none, at least not effectively. Don’t simply consider the search terms that are being targeted with the current site, make sure that these are the most effective terms to go after.

19. What pages and search terms are currently drawing traffic?

If there are pages on the site that are currently doing very well with search engines, you’ll probably not want to make major changes to the content of those pages. This can easily be overlooked during a redesign, but making excessive changes to pages that are ranking well can kill the rankings. Likewise, what search terms are currently producing traffic? Be sure that they are used in the new design.

20. What pages currently have inbound links?

Whatever pages on the site have a significant number of inbound links or are drawing traffic through those links, you’ll want to make sure that any changes do not negatively affect these links. If possible, use the same URL structure. If not, be sure to re-direct visitors to the appropriate page.

21. What will make visitors want to come back?

Most likely you’ve considered how the new design can make a solid first impression, but what is it about the website that will keep visitors coming back for more?

Wednesday, January 23, 2008 1:46:32 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Design | Programming | Web Design
# Tuesday, January 22, 2008
Prototype 1.6+ cheat sheet

A long awaited Prototype cheat sheet - a full reference to a bleeding edge 1.6.0.2 is finally here. I had no experience creating something like this before, so any bugs or suggestions are very much appreciated. Couple of notes about notations:

  • Modules are sorted in a somewhat logical order - those commonly used are mostly in the left/center area, while deprecated/utility methods are all the way to the right
  • Method can be recognized by parentheses following it (anything that doesn’t have ones is a property)
  • Deprecated items are marked red and have NO parentheses/arguments specified
  • Prototype extends quite few native objects’ prototypes with a set of convenient methods. In such cases there’s an explicit note about it next to a module name - i.g. stripScripts() method from “String (String.prototype)” can be called as 'foo'.stripScripts()
  • When a module is also a class, there’s a “(constructor)” note next to it - i.g. “Hash (constructor)” means that it should be called as new Hash()
  • There are few bonus items (such as those from Prototype.Browser) which are not yet included in documentation

Download and Enjoy!

Update:

I have managed to choose the most retarded format for the cheat sheet - almost squared - which was impossible to print or navigate.
Sincere apologies.

There is an updated version at the same address which also fixes few other annoyances:

  • Ajax.Responders is now a separate section
  • Added missing Event.fire
  • Added Prototype.BrowserFeatures.XPath
  • Added simple “Dimensions/Offsets” diagram
  • Minor rearrangements
Tuesday, January 22, 2008 11:18:20 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
AJAX | Javascript | Programming | Visual Studio
# Monday, January 21, 2008

If you are like me, you hate hand editing HTML and XML!  But unfortunately, as a .NET Developer you often find yourself doing it, and if for no other reason, you have to do it for parts of the Web.Config and Application.Config files. Last night, I was googling for something, and just found this tool from ASPhere by luck. It's really easy, nice, and looks great :)

Here you are the URL : http://asphere.aspweb.cz/default.aspx

Monday, January 21, 2008 1:42:53 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Thursday, January 17, 2008

Under the category of "you learn something new every day": While watching dnrTV this morning, I saw something that I've never seen done in C# before.

I knew that it was possible to make an "alias" for a namespace in C#. For example, if you have a complex namespace like MadProps.Windows.Controls (a contrived example) that you don't want to add to your "using" list, but you don't want to have to retype every time, you can use code like this to "alias" it:

using MPControls = MadProps.Windows.Controls;

That means that instead of typing "MadProps.Windows.Controls.TextBox" all through your code, you can just type "MPControls.TextBox". Nice.

What I learned this morning, however, is that you can do the same thing with types! If you have a type name that's really complex (think generic types) you can create an alias for them, too!

using MyDict = System.Collections.Generic.Dictionary<int, MyLongClassName>;

Now I can just declare a variable as type "MyDict" in code instead of retyping the full dictionary definition!

Granted the uses are limited. Unless it's a particularly nasty type name I think your code readability would be best served by avoiding these sorts of aliases. However, it's great to know that the feature exists.

Thursday, January 17, 2008 2:03:39 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Tuesday, January 15, 2008

For a long time I have been looking for a really easy way to create a cryptographically random string in c#.  I knew it had to be simple but I just had not spend the time to dig one up.  Specifically I was looking for a quick and easy way to get a string that was acceptable for use as a Token for session use. 

using System;
using System.Security.Cryptography;

namespace ConsoleApplication1
{
   class Program
   {
   static void Main(string[] args)
   {
      byte[] random = new Byte[128]; //Tell it how long you want it to be
      RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
      rng.GetNonZeroBytes(random); 
      // The array is now filled with cryptographically strong random bytes.

      Console.WriteLine(System.Convert.ToBase64String(random));
         Console.ReadKey();
      }
   }
}

Tuesday, January 15, 2008 2:56:38 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Wednesday, January 09, 2008

If you are looking for a ASP.NET Google Map Control, your search is now over.

Jacob Reimers from http://www.reimers.dk/ offers a great asp.net control in 2 flavors.

The free version which lets you easily display a map with markers and/or lines and a licensed version which gives you the full power of Google Maps.

Download the free control, unzip it to your Bin folder in your web app and add a reference to it.

 

This is a sample asp.net page:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="GoogleMap" Namespace="Reimers.Map" TagPrefix="Reimers" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"> 
    <title>Google Map test</title>
</head>
<body> 
    <form id="form1" runat="server"> 
        <div> 
            <reimers:googlemap id="GMap" runat="server" width="349" height="354" onmarkerclick="GMap_MarkerClick"  /> 
        </div> 
    </form>
  </body>
</html>

and the code behind:

using System;

using System.Web.UI;

using Reimers.Map;

 

public partial class _Default : Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        GMap.GoogleKey = "Your API Code here";

        GMap.MapType = MapType.Map;

        GMap.TypeControl = MapTypeControl.None;

        GMap.MapControl = ControlType.Small;

 

        GoogleMarker testMarker = new GoogleMarker("newMarker", new GoogleLatLng(43.611611, -88.952931));

        testMarker.MarkerText = "Test Marker";

        GMap.Markers.Add(testMarker);

 

        GMap.Latitude = testMarker.Latitude;

        GMap.Longitude = testMarker.Longitude;

        GMap.Zoom = 10;

    }

 

    protected void GMap_MarkerClick(GoogleMap GMap, GoogleMarker Marker, ref String MapCommand)

    {

        MapCommand = Marker.OpenInfoWindowHTML(GMap, Marker.MarkerText);

    }

}

Wednesday, January 09, 2008 1:23:22 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Google | Programming | Visual Studio | Web 2.0

Sometimes we need to make some write to logs, trace, and maybe limit some features during debug. It's good to know that in debug mode we have precompiler identifier DEBUG is set. So, first of all you can try #if #endif construction. In my opinion, it's not very good to use #if directive, especialy if there is something better.

Conditional attribute. It can be applied to any method that returns void. Why void? Because the method call ignored if the condition is not fulfilled. The method can be static or not.

[Conditional("DEBUG")]
static void DebugMethod()
{
}

So, this is the best way to make some job in DEBUG configuration. Also, it can be used to make different build configurations.

Wednesday, January 09, 2008 1:18:13 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Sunday, January 06, 2008

JavaScript Libraries in particular have grown immensely in popularity, and the article continues to be a great resource. However, it was apparent from how the Web development community responded, that there was a single missing component. Designers and developers wanted an at-a-glance comparison chart. I considered how to go about researching and writing such a comparison, and shortly thereafter, I was contacted by Cody Lindley. He let me know that he'd been working on such a chart. Here is that chart.

  DOM Assistant 2.5 YUI 2.4.1 jQuery 1.2 Dojo 1.0 Prototype 1.6 EXT 2.0 Mootools 1.11
1
Official (complete!) documentation (API found on domain)
2
Official off-line documentation (off-line API found on domain, included in download, and managed by Dev. team)
3
Real code, with working live examples included in the API (not just demo's/tutorials out side of the API)
4
An official manual/book, not an API, not tutorials, but a manual/book online or hardcopy
5
Official real world demos included in download
6
Modular by design (one file by design, or multiple)
7
File size (KB) not minified, obfuscated, or gzip (? = depends upon what you include)
41.4 29 - ? 77.4 219 - ? 121 29 - ? 9k - ?
8
Official minified version (removing just comments and spaces)

6 - ?

44.6

7 - ?
9
Official packed/obfuscated version

21

26.2

50 - ?
10
Official hosted minified version with gzip (free, unlimited)
11
Official widgets/UI toolkit
12
SVN/CVS access
13
Unit tested
14
Public unit testing
15
Open development
16
100% Funded development (paid, full-time developers, only focus)
17
Official forum
18
Official Mailing list
19
Commercial support and training
  DOM Assistant YUI 2.4.1 jQuery 1.2 Dojo 1.0 Prototype 1.6 EXT 2.0 Mootools 1.11
20
Official plug-in architecture (was the base code designed and documented (documentation key) to facilitate open plug-in development by the community) Similar to modular, but with a different intent.
21
License type
GNU BSD GPL / MIT AFL / BSD MIT LGPL MIT
22
Free for Commercial use
 
Official support for Safari 1.3+
 
Official support for Safari 2+
 
Official suppor for Safari 3+
 
Official support for Opera 8+ Mac/Win
 
Official support for Opera 9+ Mac/Win
 
Official support for Firefox Mac/Win 1.5+
 
Official support for Firefox Mac/Win 2.0+
 
Official support for IE 7
 
Official support for IE 6
 
Official support for IE 5.5
 
Official support for IE 5.0

There are several factors to consider when compiling the necessary information for this comparison. The first, and most important, is terminology. Even though there are numerous features and functionalities for each JavaScript library that are similar, they do not always fit neatly into predetermined headings. It remains imperative that each library feature be weighted while keeping this in mind, and when appropriate, read the full description that accompanies each heading. This is a fantastic starting point for your own research and analysis.

Although the groundwork has been laid, another factor to consider is that there is still the effort to maintain an accurate comparison. Remember, this is a living document, and you should use the chart whenever you begin a new project that requires a library. After listening to developers who have used these libraries, we intend to make updates, modifications, and maybe even a major overhaul. The intent is to facilitate discussion, and to be the primary (most accurate) resource for determining which framework is right for you, and right for the task you need to accomplish.

Before the initial release, several of the programmers who are responsible for the creation of these libraries were contacted, and their opinions will always be taken into consideration. This helps us to maintain a balanced, unbiased opinion. The number of options available to developers today can be daunting, and helping you to choose the right tool should be done without any preconceived notions on our part. We will not always be able to guarantee that each of the creators of these libraries agree on our comparison criteria, but we will always take the steps necessary to listen and cooperate.

The final consideration is determining which libraries to include for comparison. This is a little easier to determine, since the decision is driven from a set of closed questions. Is the library licensed under an open-source license? Is there API documentation, and how often is it updated? How mature is the library, and how often are updates released? Is this a core library, or is it an extension/add-on/plugin to an existing library? These are not the only questions to ask, but they are a few that can help with the process of elimination.

Sunday, January 06, 2008 11:34:06 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Javascript | Programming
# Wednesday, January 02, 2008

In 2007 I've worked with NUnitForms. It contains all major controls testers and you can easily create your own ones for e.g. a Data Grid or a 3rd party control. I had to create one for Janus GridEx and it wasn't really that hard.

A little reflection went a long way :) Lately, the whole project was at a standstill for some time but now it seems it's revitalizing nicely with new people on board. So if you haven't yet go take look. This is just one open source GUI testing platform and I'm sure there are others... I haven't checked them out though.

Now to the big question: Is it worth it?  It depends...

I'm not a hardcore TDD practitioner but I like having repeatable unit tests. But having automated GUI unit tests is in my opinion a waste of time.

Why? It simply isn't worth spending time writing them. You should have enough code coverage with non GUI tests to find any bugs long before hitting the GUI. You might want to be tempted to unit test control positions or visibility or some other property... don't bother.

You'll spend your time better if you write more non GUI unit tests and check your GUI by hand (eye).

So what are they useful for? Well... I've used them for acceptance and integration testing with great success.

Integration Tests...

... test how different parts of your application work together. These kinds of GUI tests proved to be VERY useful and they are worth investing time in. They have a great ROI (return on investment) once they're written. For example we had a large workflow based application that was completely async in nature. It had a windows forms client that could be deployed on multiple computers, all those clients connected to a single server that hosted a few webservices for data modifications, retrieval and some other stuff.

The whole app was also connected to Sharepoint server,  Exchange Server, SQL Server, used InfoPath and a 3rd party software to export data from and into it. With one single GUI integration test we could easily see if everything worked together as it should. We mocked the InfoPath and 3rd party software but everything else ran great.

The point of using GUI tests here is to see how and if your whole application works with all parts integrated together from GUI interaction to Exchange connectivity. Even the best non GUI integration tests simply don't do that.

Acceptance Tests...

... test if your software is up to some specs usually defined by the business process. They're in essence a black box test. You don't care what goes on inside the software you just want to see if the output is correct for a certain input. In workflow based processes this can be very useful since you know what the input and output parameters are for your workflow.

For example you start the workflow in your app via NUnitForms, pressing "move in workflow" buttons until the workflow end and then check if the output parameters have the correct values. You can check for various different GUI parameters in this test along the way but as I said above don't go overboard. I usually just check for visibility of certain panels or grids... simple things like that.

When I first started with GUI testing I thought it was a really big waste of time. And to tell you the truth if you don't draw the line somewhere it is. I even had a moment when I thought it was a good idea to test everything only with GUI tests. That was so far over line I couldn't even see it anymore. Luckily that moment passed pretty fast. Don't make the same mistake. If used wisely automated GUI tests are a big benefit.

Wednesday, January 02, 2008 11:39:05 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | Visual Studio
# Thursday, December 27, 2007

Partial methods are a new feature available in C# 3.0 that don't seem to get enough credit. I think there was a lot of confusion early on about what partial methods were and how they were used.

Partial methods are intended to solve a major problem that is not only caused by code-generation tools and also affects those same tools. For instance, you are writing a code-generation tool but want to provide a way for the developers that are using your generated classes to hook in to specific areas of the code. As such, you don't want them editing your generated code since those customizations will be lost the next time the tool runs. On the flip side of this scenario is the developer who needs to write the code that hooks into those specific areas and doesn't want that code being lost the next time the tool runs.

Delegates are one solution to this type of problem. In the generated code, you declare a delegate method that you then call at the appropriate areas. If no one has implemented a concrete version of the delegate, the call will not do anything. However, if someone has implemented am instance of that delegate then the call will run the code in that instance. This sounds like a pretty good solution, and, until partial methods it really was the only solution. The drawback is that the code for the delegate is always compiled in to the runtime of your application and add to the runtime overhead of application (granted, that overhead is minimal but it's still there).

Partial classes helped with this problem by allowing the code-generation tools to isolate the generated code in a partial class. This allowed the developer to add their own methods to the class without fear that they would be overwritten the next time the tool ran. However, it only helped partially. In order to accomplish our scenario, you still needed to provide a delegate to allow the developer to hook into your process.

If we take this a step further and look at partial methods, you will start to see how they work and what the benefit is of using them. The following rules govern how partials methods can be declared and used:

  1. Must be declared inside a partial class.
  2. Must be declared as a void return type.
  3. Must be declared with the partial.
  4. Cannot be marked as extern.
  5. Can be marked static or unsafe.
  6. Can be generic.
  7. Can have ref but not out parameters.
  8. Cannot be referenced as a delegate until they are implemented
  9. Cannot have access modifiers such as public, private or internal.
  10. Cannot be declared as virtual.

Partial methods are implicitly marked as private. This means they cannot be called from outside the partial class.

Now that we have the rules out of the way, let's take a look at an example. This is a completely contrived example, as you typically wouldn't declare both portions of the partial class yourself.

   1: // This is the class that would normally have been autogenerated.
   2: public partial class CustomTypedCollection
   3: {
   4:     partial void BeforeAddingElement(CustomElement element);
   5:  
   6:     public void AddElement(CustomElement element)
   7:     {
   8:         BeforeAddingElement();
   9:     }
  10: }
  11:  
  12: public partial class CustomTypedCollection
  13: {
  14:     partial void BeforeAddingElement(CustomElement element)
  15:     {
  16:         Console.WriteLine("Element " + element + " is being added.");
  17:     }
  18: }
  19:  
  20: class Program
  21: {
  22:     static void Main(string[] args)
  23:     {
  24:         CustomTypedCollection c = new CustomTypedCollection();
  25:         c.AddElemeent(new CustomElement());
  26:     }
  27: }

In this example, the code-generation tool declares a partial method BeforeAddingElement. It is declared as just a function prototype with no implementation. Effectively, this tells the developer that if they want to hook in to the AddElement process, they can do so by declaring an implementation of the BeforeAddingElement method. If an implementation is declared, the implementation and the call inside AddElement will be compiled in to the runtime code. However, if no implementation is declared the call will be optimized by the compiler and it will be entirely eliminated in the runtime code.

This mechanism provides a lot of the same flexibility as delegates without the runtime overhead. It also allows the developer to work with a much smaller implementation of their portion of the partial class that contains only the few partial methods that have been implemented.

Thursday, December 27, 2007 7:53:47 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Wednesday, December 26, 2007

What does Assembla do?
Assembla provides tools and services for building software quickly using global teams.

Is the service free?
Yes, the online service is free for individuals and small groups. We make money when we have larger groups that need premium tools, portfolios, and private servers.

500MB of SVN for free…

I have been using Subversion for project work for some time now, and it seems that most agree that it is the best Open Source solution available. I have enjoyed the use of SVN provided by clients or employers, but only recently started considering replacing my old local VSS server with a web-enabled SVN server of my own. My motivation is to get code that I own off-site and have some redundancy along with improved accessibility. I am also interested leveraging the benefits of the continual development and refinement of SVN as an Open Source project. TortoiseSVN is a good example of that.

I started by researching the requirements for installing SVN server. Installation on a local Windows host seemed doable, but I wanted to install it on my web server. Since my host doesn’t support applications, I’m on my own. I don’t even know what OS the server is running. From what I’ve read, installing SVN on a site would be a chore. Plus it would compete for space with site content. An alternative would be to pay for a specialized SVN hosting service. Hard to justify the continual overhead for that.

So I Googled for free SVN. One result stood out as promising: Assembla. They give away a 500mb SVN account with unlimited users and an integrated bug tracking setup (Trac). For the quick, small projects I am looking to use it for, I can accept the risk that Assembla flakes out as a business entity. Worst case I will still have my latest build on my local. Assembla’s business model seems pretty sound to me anyway - a successful freelance coder will eventuallly need more space if they get cosy using the free service and will become a paying customer.

Here aro some of the Assembla tools:

Subversion

Subversion is the most popular centralized source code repository and version control system.  Our subversion includes email alerts on commit, Trac code browsing, and a post-commit hook to trigger.  And, we know that reliability is important for subversion users, so we backup to failover servers in real time.  Learn more.

Trac

Trac is a popular open source ticketing system, with the mission to "help developers write great software while staying out of the way."   You can import and export trac projects from Assembla.  We enhance trac with simplified team management, HTML alerts (called "notifications" in trac), and hourly and weekly alert summaries.  We support a few trac plugins, including XML-RPC for Eclipse integration.

Scrum

The scrum tool collects reports from your team members in the stand-up meeting format:  "What did I do, What will I do, What do I need."

Chat

The chat tool provides a persistent chat room that you can use for daily meetings or just to drop in.

Wednesday, December 26, 2007 8:11:34 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming | Project Management | Site Reviews | SVN | Web 2.0
# Sunday, December 23, 2007

Taken From: TechDune

Internet Explorer has cool add-ons which make the job of website designers and developers much easier. Here is my list of 20+ excellent Firefox add-ons that every web developer and designer should know about.


Internet Explorer Developer Toolbar
Variety of tools for quickly creating, understanding, and troubleshooting Web pages.

IE Watch
Allows you to view and analyze HTTP/HTTPS headers, Cookies, GET queries and POST data.

IE Web Developer
Allows you to inspect and edit the live HTML DOM, evaluate expressions and display error messages, explore source code of Web page and monitor DHTML Event and HTTP Traffic.

IESpy
Allows one to inspect or manipulate the DOM of any IE Web browser control.

DebugBar
Brings new services to surfers and professionals. Surfers: zoom, direct Web search, e-mail page screenshots, and color picker. Developers: view HTML code, cookies, JavaScript, HTTP/HTTPS headers, and miscellaneous information.

Virtual Machine
Allows you to view java applets on Web pages.

Microsoft Fiddler
Logs all HTTP traffic between your computer and the Internet.

Tangram Xtml Designer
Visual designer for IE Band Object, activeX Control and .NET user control.

Http Watch
HttpWatch shows you HTTP and HTTPS traffic from within IE allowing you to quickly debug, fix and optimize your Web site.

Embedded Web Browser
The package contains all the programmer need to extend the development of a Web browser.

CGToolbar
Must have tool for CG Artists, Animators, VFX and 3d professionals.

Site Studio 6
Build rich content Web sites, with no HTML skills required.

Haptek Player
An ActiveX control and Netscape Navigator Plugin that allows any webpage or application (with ActiveX support) to include Haptek’s Autonomous characters.

Flash2X Flash Hunter

Save Flash movies from web pages.

iOpus iMacros
Check the same sites every day,data upload, online marketing and functional testing and regression testing Web sites:

Telerik RadToolBar
A flexible component for implementation of tool and button strips, needed in most web applications.

UltraEdit-32
Powerful Text, HEX, HTML, PHP and Programmer’s Editor.

Bytescout Post2Blog
Freeware powerful blog editor for WordPress, Typepad, MovableType and other blogs.

Search Monster
Free Flash Web Directory & Internet Search Engine is the Flash-remoting Web directory instant content for you Web site.

Zend Studio
Encompasses all the development components necessary for the full PHP application.

DbaBar
Integrated toolbar enabling Oracle Database Administrators to browse their databases from within Internet Explorer within minutes after installation.

Explorer Toolbar Maker
lets you create your own Explorer bar from any HTML page, picture, Macromedia Flash file, or Microsoft Office document.

Sunday, December 23, 2007 1:40:15 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Design | Javascript | Programming
# Thursday, December 20, 2007

Let’s say you want to change the color of your links on just your contact page to red. They are blue on every other page, but it just makes sense for them to be red on your contact page (for some reason). There are a couple ways you could go about this.

  • You could declare a separate stylesheet for your contact page.
    This isn’t ideal, because it’s redundant. If you make any other changes, you’ll always have to make them both on the main stylesheet and the contact page stylesheet.
      
  • You could give all those links a unique class on that page.
    This isn’t ideal, because it isn’t very semantic and it’s also redundant. Why apply a class to every single link on the page when they really aren’t any different from links elsewhere on the site, contextually speaking?
      
  • The best solution is to give your the body a unique ID.
    This solves the problem perfectly. You can use the same stylesheet and target just the links you want to with a single CSS selector.
      

Simple, literally just apply the ID to the body tag:

   ...
</head>

<body id="contact-page">
   ...

Now for our example of making all links on the contact page red instead of blue, just use some CSS like this:

a {
color: blue;
}

#contact-page a {
   color: red;
}
Thursday, December 20, 2007 6:45:41 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Design | Programming

If you want to store configuration information in a XML file, you can easily use serialization to assist you. Instead of using XPath or DOM, and have some code to maintain, simply use the XmlSerializer to retrieve information.

Here's an example of a XML file:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <DatabaseConfig>
  3.   <Data>
  4.     <DatabaseConfigData
  5.       File="Data/Principal.xml"
  6.       EntityName="Principal"
  7.       Format="Xml" />
  8.     <DatabaseConfigData
  9.       File="Data/Role.xml"
  10.       EntityName="Role"
  11.       Format="Xml" />
  12.   </Data>
  13. </DatabaseConfig>

 

And if you have the following classes (C#):

  1. public class DatabaseConfig
  2. {
  3.     public DatabaseConfigData[] Data { get; set; }
  4. };
  5.  
  6. public class DatabaseConfigData
  7. {
  8.     [System.Xml.Serialization.XmlAttribute()]
  9.     public string File { get; set; }
  10.  
  11.     [System.Xml.Serialization.XmlAttribute()]
  12.     public string EntityName { get; set; }
  13.  
  14.     [System.Xml.Serialization.XmlAttribute()]
  15.     public string Format { get; set; }
  16. };

 

All you have to do to load the XML information into the DatabaseConfig class is (C#):

  1. DatabaseConfig GetDatabaseConfig(string file)
  2. {
  3.     XmlSerializer serializer =
  4.         new XmlSerializer(typeof(DatabaseConfig));
  5.     using (StreamReader reader = new StreamReader(file))
  6.     {
  7.         object obj = serializer.Deserialize(reader);
  8.         return (DatabaseConfig)obj;
  9.     }
  10. }

There are a few issues you have to handle when using XML Serialization, wich you can see at my earlier posts about XMLXSD and Serialization.

Thursday, December 20, 2007 6:35:13 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Serialization | XML
# Wednesday, December 19, 2007

The good folks at Ajaxian.com and I just completed our third annual survey of Ajax tools usage.  The raw data is free for everyone here - you should be able to slice it and dice it anyway you see fit.  The top 10 Ajax toolkits in 2007 are:

Dec2007top10_2

You can check out the top 10 Ajax toolkits from 2006 and 2005 at the end of this blog.

What is interesting about the Ajax market is that it's more diversified in 2007 than it was in 2005 - the number  of toolkits keep growing and jostling position in terms of usage.  Right now there are 241 Ajax toolkits and related libraries listed in the survey. There were about three dozen in 2005 and 170 in 2006.  The number of options is growing.

That's brings up another point: The survey is not limited to Ajax frameworks and toolkits, it also includes some JavaScript libraries commonly used in Ajax development. All of the entries were derived from Ajaxpatterns.org as well as past surveys. There are probably quite a few of these frameworks that have been abandoned and others that were missed, so its not a perfect record of available Ajax toolkits and libraries today.

Prototype and Script.aculo.us are the only toolkits to maintain a lead over the past three years.  However, over all there are no clear winners or losers as even the strongest incumbents (i.e., Prototype and Script.aculo.us) are starting too loose ground. Some frameworks initially popular have faded nearly completely out of the market (i.e., xajax and Rico ) while others have have sprung out of nowhere to become leading tookits (i.e., jQuery and Ext JS).    The changes over the past three years are easy to see in the stack chart at the end of this blog, which shows the market share of the most popular toolkits - notice how they grow and shrink in market share. That means that the market remains immature.

What is astonishing is the nearly complete lack of commercial Ajax frameworks. Backbase has had a lot of success making a comeback after loosing some market share in 2006, but other commercial Ajax frameworks have not been so lucky. 

Spry is growing quickly and may be in the top 10 next year. Spry was left out of the survey for the first day or so and then added in as it was the most popular write in toolkit.  It may have faired better if it was an option from the start. I added up all the write-ins for Spry with picks after the survey was adjusted. The numbers are not great - Spry has about 4% of the market right now

The number of responses were much higher this year (2,619) compared to 2006 (865) and 2005 (763).   The increase is enough to say that Ajaxian.com has become more popular and so has Ajax but you can't go much beyond that. In addition, the entire survey has to be taken with a large licking-block of salt. It's not scientific and probably breaks about 100 rules for best practices when doing a survey.  However, given the limitations of the survey and the surveyor (that's me), it still provides valuable insight to the Ajax toolkit market in general.

Wednesday, December 19, 2007 10:52:22 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Programming

Which .NET Framework Data Provider to Use?

To achieve the best performance for your application, use the .NET Framework data provider that is most appropriate for your data source. There are a number of data provider options for use in your applications. The following table provides information about the available data providers and which data sources a data provider is most appropriate for.

Provider

Details

SQL Server .NET Data Provider

Found in the System.Data.SqlClient namespace.

Recommended for middle-tier applications using Microsoft SQL Server version 7.0 or later.

Recommended for single-tier applications using the Microsoft Data Engine (MSDE) or Microsoft SQL Server 7.0 or later.

OLE DB .NET Data Provider

Found in the System.Data.OleDb namespace.

Recommended for middle-tier applications using Microsoft SQL Server 6.5 or earlier, or any OLE DB provider that supports the OLE DB interfaces listed in OLE DB Interfaces Used by the OLE DB .NET Data Provider in the .NET Framework SDK.

For Microsoft SQL Server 7.0 or later, the .NET Framework Data Provider for SQL Server is recommended.

Recommended for single-tier applications using a Microsoft® Access database. Use of an Access database for a middle-tier application is not recommended.

ODBC .NET Data Provider

Found in the Microsoft.Data.Odbc namespace.

The ODBC .NET Data Provider is available for download.

Provides access to data sources that are connected to using an ODBC driver.

Oracle .NET Data Provider

Found in the System.Data.OracleClient namespace.

The .NET Framework Data Provider for Oracle, unlike the Microsoft OLE DB provider for Oracle, also supports new Oracle 9i datatypes, as well as ref cursors (useful for running Oracle stored procedures that return result sets). This provider, System.Data.OracleClient, is similar to the .NET Framework Data Provider for SQL Server, System.Data.SqlClient.

The Oracle .NET Data Provider is available for download


The fastest database read mechanism will be ADO.NET Data Readers, as opposed to Data Sets.

Wednesday, December 19, 2007 9:40:12 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming | Visual Studio
# Tuesday, December 18, 2007

Web design is simpler than ever, and that's a good thing. web 2.0 design means focused, clean and simple design that is all about the content.

Why simplicity is good?

  1. Web sites have goals and all web pages have purposes.
  2. Users' attention is a finite resource.
  3. It's the designer's job to help users to find what they want (or to notice what the site wants them to notice)
  4. Stuff on the screen attracts the eye. The more stuff there is, the more different things there are to notice, and the less likely a user is to notice the important stuff.
  5. So we need to enable certain communication, and we also need to minimise noise. That means we need to find a solution that's does its stuff with as little as possible. That's economy, or simplicity.

How?

There are two important aspects to achieving success with simplicity:

  1. Remove unnecessary components, without sacrificing effectiveness.
  2. Try out alternative solutions that achieve the same result more simply.

Whenever you're designing, take it as a discipline consciously to remove all unnecessary visual elements.

Concentrate particularly on areas of the layout that are less relevant to the purpose of a page, because visual activity in these areas will distract attention from the key content and navigation.

Use visual detail - whether lines, words, shapes, colour - to communicate the relevant information, not just to decorate.

Tuesday, December 18, 2007 10:38:00 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Programming | Web 2.0 | Design

When it comes to designing and developing a web site the load time is one consideration that is often ignored, or is an afterthought once the majority of the design and structure is in place.  While high-speed internet connections are becoming increasingly common there are still a significant portion of web users out there with 56k connections, and even those with broadband connections aren't guaranteed to have a fast connection to your particular server.  Every second that a user has to wait to download your content is increasing the chance of that user deciding to move on.

Attempting to reduce the size of a web page is usually restricted to compressing larger images and optimizing them for web use.  This is a necessary step to managing page size, but there is another important factor that can significantly reduce the size of a page to improve download times.  Getting rid of that code bloat means less actual bytes to be downloaded by clients, as well as captilizing on what the client has already downloaded.  Unfortunately this is an option that tends to be ignored due to the perceived loss of time spent combing through markup to cut out the chaff, despite the fact that clean, efficient markup with well-planned style definitions will save countless hours when it comes to upkeep and maintenance.

To demonstrate the difference between a bloated page and one with efficient markup I created two basic pages. One uses tables, font tags, HTML style attributes and so forth to control the structure and look of the page, while the other uses minimal markup with an external stylesheet.

1) Bloated Page

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>This Tag Soup Is Really Thick</title>
<meta name="description" content="The end result of lazy web page design resulting in a bloated mess of HTML.">
<meta name="keywords" content="tag soup, messy html, bloated html">
</head>
<body>
<center>
  <table width=700 height=800 bgcolor="gainsboro" border=0 cellpadding=0 cellspacing=0>
    <tr>
      <td valign=top width=150><table align=center border=0 cellpadding=0 cellspacing=0>
          <tr>
            <td align="left"><a href="#home" title="Not a real link"><font color="#4FB322" size="3"
             face="Geneva, Arial, Helvetica, sans-serif">Home Page</font></a></td>
          </tr>
          <tr>
            <td align="left"><a href="#about" title="Not a real link"><font color="#4FB322" size="3"
            face="Geneva, Arial, Helvetica, sans-serif">About Me</font></a></td>
          </tr>
          <tr>
            <td align="left"><a href="#links" title="Not a real link"><font color="#4FB322" size="3"
            face="Geneva, Arial, Helvetica, sans-serif">Links</font></a></td>
          </tr>
        </table></td>
      <td valign=top><table>
          <tr>
            <td align="center" height=64><h1><font color="red" face="Geneva, Arial, Helvetica, sans-
            serif">Welcome to My Site!</font></h1></td>
          </tr>
          <tr>
            <td align="left"><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-
             serif">Isn&acute;t it surprisingly ugly and bland?</font></td>
          </tr>
          <tr>
            <td align="left"><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-serif">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce est. Maecenas pharetra nibh vel turpis molestie gravida. Integer convallis odio eu nulla. Vivamus eget turpis eu neque dignissim dignissim. Fusce vel erat ut turpis pharetra molestie. Cras sollicitudin consequat sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas augue diam, sagittis eget, cursus at, vulputate at, nisl. Etiam scelerisque molestie nibh. Suspendisse ornare dignissim enim. Sed posuere nunc a lectus. Vestibulum luctus, nibh feugiat convallis ornare, lorem neque volutpat risus, a dapibus odio justo at erat. Donec vel lacus id urna luctus tincidunt. Morbi nunc. Donec fringilla sapien nec lectus. Duis at felis a leo porta tempor.</font></td>
          </tr>
          <tr>
            <td align="left"><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-serif">Maecenas malesuada felis id mauris. Ut nibh eros, vestibulum nec, ornare sollicitudin, hendrerit et, ligula. Suspendisse tellus elit, rutrum ut, tempor eget, porta bibendum, magna. Nunc sem dolor, pharetra ut, fermentum in, consequat vitae, velit. Vestibulum in ipsum. Phasellus erat. Sed eget turpis tristique eros cursus gravida. Vestibulum quis pede a libero elementum varius. Nullam feugiat accumsan enim. Aenean nec mi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</font></td>
          </tr>
          <tr>
            <td align="left"><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-serif">Aenean vel neque ac orci sagittis tristique. Phasellus cursus quam a mauris. Donec posuere pede a nisl. Curabitur nec ligula eu nibh accumsan sagittis. Integer lacinia. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Praesent tortor dolor, pellentesque eget, fermentum vel, mollis ut, erat. Nullam mollis. Cras rhoncus tellus ut neque. Pellentesque sed ante.</font></td>
          </tr>
          <tr align="left">
            <td><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-serif">Donec at nunc. Nulla elementum porta elit. Donec bibendum. Fusce elit ligula, gravida et, tincidunt et, aliquam sit amet, metus. Nulla id magna. Fusce quis eros. Sed eget justo. Vivamus dictum interdum quam. Curabitur malesuada. Proin id metus. Curabitur feugiat. Nunc in turpis. Cras lobortis lobortis felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris imperdiet aliquet ante. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</font></td>
          </tr>
          <tr align="left">
            <td><font color="#FFFFFF" size="3" face="Geneva, Arial, Helvetica, sans-serif">Etiam tristique mauris at nibh sodales pretium. In lorem eros, laoreet eget, rhoncus et, lacinia nec, pede. Fusce a quam. Pellentesque vitae lacus. Vivamus commodo. Morbi euismod, ipsum id consectetuer ornare, nisi sem suscipit pede, vel dictum purus mauris eu leo. Proin sodales. Aliquam in pede nec eros aliquet adipiscing. Nulla a purus sed risus ullamcorper tempus. Nunc neque magna, fringilla quis, ullamcorper vitae, placerat sed, orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</font></td>
          </tr>
        </table></td>
    </tr>
  </table>
</center>
</body>
</html>

 

2) Cleaned Page

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Less Markup, More Content</title>
    <meta name="description" content="The end result of lazy web page design resulting in a bloated mess of HTML.">
    <meta name="keywords" content="tag soup, messy html, bloated html">
    <link href="style.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="content">
      <ul class="menu">
        <li><a href="#home" title="Not a real link">Home Page</a></li>
        <li><a href="#home" title="Not a real link">About Me</a></li>
        <li><a href="#home" title="Not a real link">Links</a></li>
      </ul>
      <h1>Welcome To My Site!</h1>
      <p>Isn&acute;t it suprisingly ugly and bland?</p>
      <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce est.  Maecenas pharetra nibh vel turpis molestie gravida. Integer convallis  odio eu nulla. Vivamus eget turpis eu neque dignissim dignissim. Fusce  vel erat ut turpis pharetra molestie. Cras sollicitudin consequat sem.  Vestibulum ante ipsum primis in faucibus orci luctus et ultrices  posuere cubiliaCurae; Maecenas augue diam, sagittis eget, cursus at,  vulputate at, nisl. Etiam scelerisque molestie nibh. Suspendisse ornare  dignissim enim. Sed posuere nunc a lectus. Vestibulum luctus, nibh  feugiat convallis ornare, lorem neque volutpat risus, a dapibus odio  justo at erat. Donec vel lacus id urna luctus tincidunt. Morbi nunc.  Donec fringilla sapien nec lectus. Duis at felis a leo porta tempor. </p>
      <p>Maecenas malesuada felis id mauris. Ut nibh eros, vestibulum nec,  ornare sollicitudin, hendrerit et, ligula. Suspendisse tellus elit,  rutrum ut, tempor eget, porta bibendum, magna. Nunc sem dolor, pharetra  ut, fermentum in, consequat vitae, velit. Vestibulum in ipsum.  Phasellus erat. Sed eget turpis tristique eros cursus gravida.  Vestibulum quis pede a libero elementum varius. Nullam feugiat accumsan  enim. Aenean nec mi. Vestibulum ante ipsum primis in faucibus orci  luctus et ultrices posuere cubilia Curae; </p>
      <p>Aenean vel neque ac orci sagittis tristique. Phasellus cursus quam a  mauris. Donec posuere pede a nisl. Curabitur nec ligula eu nibh  accumsan sagittis. Integer lacinia. Class aptent taciti sociosqu ad  litora torquent per conubia nostra, per inceptos hymenaeos. Praesent  tortor dolor, pellentesque eget, fermentum vel, mollis ut, erat. Nullam  mollis. Cras rhoncus tellus ut neque. Pellentesque sed ante. </p>
      <p>Donec at nunc. Nulla elementum porta elit. Donec bibendum. Fusce  elit ligula, gravida et, tincidunt et, aliquam sit amet, metus. Nulla  id magna. Fusce quis eros. Sed eget justo. Vivamus dictum interdum  quam. Curabitur malesuada. Proin id metus. Curabitur feugiat. Nunc in  turpis. Cras lobortis lobortis felis. Pellentesque habitant morbi  tristique senectus et netus et malesuada fames ac turpis egestas.  Mauris imperdiet aliquet ante. Lorem ipsum dolor sit amet, consectetuer  adipiscing elit. </p>
      <p>Etiam tristique mauris at nibh sodales pretium. In lorem eros,  laoreet eget, rhoncus et, lacinia nec, pede. Fusce a quam. Pellentesque  vitae lacus. Vivamus commodo. Morbi euismod, ipsum id consectetuer  ornare, nisi sem suscipit pede, vel dictum purus mauris eu leo. Proin  sodales. Aliquam in pede nec eros aliquet adipiscing. Nulla a purus sed  risus ullamcorper tempus. Nunc neque magna, fringilla quis, ullamcorper  vitae, placerat sed, orci. Pellentesque habitant morbi tristique  senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante  ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; </p>
    </div>
  </body>
</html>
 
 
External Style Sheet
 
@charset "utf-8";
body{font:13pt Geneva, Arial, Helvetica, sans-serif;}
.menu{float:left;height:800px;list-style-type:none;width:150px;}
.menu a, .menu a:visited{color:#4FB322;}
.content{background:gainsboro;color:white;margin:auto;position:relative;width:700px;}
h1{color:red;line-height:64px;text-align:center;}
p{margin:4px;}
 

Even in this basic example you can see a fairly dramatic improvement when the excess HTML is trimmed and CSS is used to control style.  The original page is 51 lines, where the cleaned page is only 26 lines, plus 7 lines in the style sheet.  The cleaned page is a third the size of the original (counting the style sheet), and more realistically is actually half the size because the style sheet would be cached by most client browsers and wouldn't be downloaded for every page request.  As far as raw kilobytes it's a difference of 6KB to 4KB, which isn't a particularly exciting difference in this case, but one that is quickly magnified as the length of the page increases.  This is especially true with dynamic applications that pull content from a database, most importantly content such as product listings that utilize the same markup and are repeated multiple times. Fortunately in the case of dynamic pages involving looping procedures that output the same markup with different content, cutting down the bloat can be as easy as a few modifications to those procedures.

Furthermore if you wanted to change, for instance, the font color or the line-height in the original, you would have to modify every font tag and table cell to accomplish that.  Implementing those changes in the second example requires a single modification to the style-sheet.  The time-saved here is once again significantly amplified when considered in a situation with multiple pages (in many cases this can be hundreds or even thousands).

When all is said and done, this isn't meant to be a be-all end-all guide for optimizing your markup because I could write a book and still not cover it all.  Rather it was meant to highlight an aspect of web page performance and optimization that is usually swept under the rug in favour of those that are more directly appreciable such as eye-candy and new features.  While clean markup might not be as "glamourous" as other aspects of web development, it is an important aspect to keeping load time in check and a crucial factor in reducing them amount of time spent maintaining and updating.

Tuesday, December 18, 2007 10:24:34 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Programming
# Saturday, December 15, 2007

PDFsharp is the Open Source library that easily creates PDF documents from any .NET language.

The same drawing routines can be used to create PDF documents, draw on the screen, or send output to any printer.

Here are just a few highlights:

  • Creates PDF documents on the fly from any .Net language
  • Easy to understand object model to compose documents
  • One source code for drawing on a PDF page as well as in a window or on the printer
  • Modify, merge, and split existing PDF files
  • Images with transparency (color mask, monochrome mask, alpha mask)
  • Newly designed from scratch and written entirely in C#
  • The graphical classes go well with .Net
  • Includes MigraDoc Lite for high level text layouting (you can use both PDFsharp and MigraDoc Lite in one document)

Hello World Sample

This sample shows how to create a PDF document, add a page, draw some text, and save it to disk.

// Create a new PDF document
PdfDocument document = new PdfDocument();
 
// Create an empty page
PdfPage page = document.AddPage();
 
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
 
// Create a font
XFont font = new XFont("Verdana", 20, XFontStyle.Bold);
 
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black,
  new XRect(0, 0, page.Width, page.Height),
  XStringFormat.Center);
 
// Save the document...
string filename = "HelloWorld.pdf";
document.Save(filename);
// ...and start a viewer.
Process.Start(filename);
The result is this:
HelloWorld.pdf (2.41 KB)

Saturday, December 15, 2007 10:59:35 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Programming
# Monday, December 10, 2007

Today, Google released their Chart API. Basically, the Google Chart API allows you to dynamically generate charts for use in your web applications. All you do is pass your data in the querystring and an image is returned. This isn't really a service to get too excited about, but it is pretty simple to use and it's Free.

Here is a bit about this:

The Google Chart API lets you dynamically generate charts. To see the Chart API in action, open up a browser window and copy the following URL into it:

http://chart.apis.google.com/chart?cht=p3&chd=s:hW&chs=250x100&chl=Hello|World

Press the Enter or Return key and - presto! - you should see the following image:

Yellow line chart

I decided to code up a small ASP.NET Server Control that uses the Google Chart API to put simple line graph charts on a page.

How to use this control:

Put the Chart control on the page:

<GoogleAPI:Chart runat="server" id="Chart1" 
   Width="200" Height="150" LineColor="ff0000"
   BackgroundColor="efefef"
   ToolTip="Hello World">
</GoogleAPI:Chart>

In the page load event define the values to be charted:

Chart1.MaxValue = 60;

Chart1.Values.Clear();

Chart1.Values.Add("Jan", 10);
Chart1.Values.Add("Feb", 20);
Chart1.Values.Add("Mar", 30);
Chart1.Values.Add("Apr", 50);
Chart1.Values.Add("May", 5);
Chart1.YAxisLabels.Add("0 Kb");
Chart1.YAxisLabels.Add("25+ Kb");
Chart1.YAxisLabels.Add("50+ Kb");

And, that's all you have to do to put a Chart on your page using the control.

The result is this:

Download the example / source code here: GoogleChartAPI.rar (3.33 KB)

Monday, December 10, 2007 4:21:29 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Google | Programming | Visual Studio
# Sunday, December 09, 2007

Last week (december 5th) Microsoft announced the Volta technology preview, a developer toolset for building multi-tier web applications using existing and familiar tools, techniques and patterns.

Volta’s declarative tier-splitting enables developers to postpone architectural decisions about distribution until the last possible responsible moment. Also, thanks to a shared programming model across multiple-tiers, Volta enables new end-to-end profiling and testing for higher levels of application performance, robustness, and reliability. In effect, Volta extends the .NET platform to further enable the development of software+services applications, using existing and familiar tools and techniques.

You architect and build your application as a .NET client application, assigning the portions of the application that run on the server tier and client tier late in the development process.

After tier assignments, Volta's deep integration with Visual Studio debugger and testing infrastructure dramatically improves the deployment experience for developers.

  • Volta automatically creates communication, serialization, and remoting code. Developers simply write custom attributes on classes or methods to tell Volta the tier on which to run them.
  • Developers may base tier assignments on any criteria, such as load management, performance, or location of critical assets and capabilities. Because Volta automates the hidden plumbing code, it is easy for developers to experiment with varying assignments of classes and methods to tiers.
  • Developers can use all the .NET languages, libraries, and tools they already know, including debuggers, profilers, test generators, refactoring, and code analysis tools.

Volta offers deep integration with Visual Studio 2008, including debuggers, profilers, and testing frameworks. Developers can step through code seamlessly from one tier to another, can set breakpoints on any tier, and trace flows of control across distributed systems.

What do you need to use Volta?

The Volta developer toolset requires Visual Studio 2008 and the .NET Framework 3.5 for writing and building applications. Volta applications run virtually anywhere, even where an MSIL runtime is not available. A Volta client-side application can run in most standards-compliant browsers, but can also be targetted also take advantage of MSIL runtimes like the .NET CLR.
 
All this sounds great, except the requirements that are trying to enforce the developers to use Visual Studio 2008 and the new .NET Framework 3.5.
 
I wonder why the long wait for this release? And why it does not compatible with .NET Framework 2.0?
 
BTW, It is just me or the Volta logo reminds firefox logo a bit:
 

  <- VS ->   

Sunday, December 09, 2007 2:41:46 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Microsoft | Programming | Visual Studio | Volta
# Thursday, December 06, 2007

There's no Gphone just yet, but Google does want a big piece of your cell phone. In November 2007, the company announced its Android mobile operating system, and 34 companies are on board to develop applications for the cell-phone platform as part of the Open Handset Alliance. The open software platform is hoped to go head-to-head with smartphone software from RIM, Apple, Microsoft, Nokia, and Palm. Will Google be your next mobile OS?

What's that all mean? The big motivation for Google is that it will likely have its applications such as Gmail and Google Docs & Spreadsheets automatically built into a major share of new cell phones in the burgeoning market.

What's interesting and exciting is that the platform--likely based on Linux--will be open to all third-party developers. With any luck, that means that consumers will finally be able to choose exactly which software apps they want to use on their cell phones.

Google CEO Eric Schmidt claims that "as a result of this platform you'll be able to do amazing things with your mobile devices that you've never thought of." We'll get a first peek at the possibilities for programmers with an early look at a software development kit for Google Android next week.

 

Thursday, December 06, 2007 2:16:21 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
Google | Programming
# Tuesday, December 04, 2007

This is one of those "Yeah I've always seen people use it differently but I don't know why!" questions.

Re-throwing exceptions can be misused, although it may not cause any harm to your application - there are multiple ways of re-throwing an exception, most likely for the purpose of bubbling it up to a higher level.

Lets look at how many ways we can use throw:

    1. throw
    2. throw ex
    3. throw new Exception(); 

You should not use #3 except if you are throwing a specific exception other that the one that was fired such as a custom exception. To re-throw an exception in .NET your best option is #1 instead of #2 and that is simply because of how they stack up in the stack trace. Lets take a look at the stack trace for both instances using the following snippet.

 

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            DoMath();
        }
        catch(Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// A method that simply calls another method.
    /// </summary>
    /// <remarks>
    /// Just a helper to show stack trace
    /// </remarks>
    private void DoMath()
    {
        MethodWithError();
    }

    /// <summary>
    /// This method will throw an error
    /// </summary>
    private void MethodWithError()
    {
        throw new Exception("Generic exception");
    }

 

The stack trace looks like this:

[Exception: Generic exception]
   throwerror.Page_Load(Object sender, EventArgs e) 
in d:\My Websites\demoweb\throwerror.aspx.cs:22
   System.Web.Util.CalliHelper.EventArgFunctionCaller
(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback
(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, 
Boolean includeStagesAfterAsyncPoint) +1061

 

However, if I replace "throw ex;" with just "throw;", here is the new stack trace.

[Exception: Generic exception]
   throwerror.MethodWithError() in d:\My Websites\demoweb\throwerror.aspx.cs:42
   throwerror.DoMath() in d:\My Websites\demoweb\throwerror.aspx.cs:34
   throwerror.Page_Load(Object sender, EventArgs e) in d:\My Websites\demoweb\throwerror.aspx.cs:22
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061

 

Its all about the details. Obviously, using just "throw;" gives us much more details - so use "throw" to re-throw an error.

Tuesday, December 04, 2007 5:10:06 PM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | Visual Studio | Programming
Navigation
Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Guy Levin
Sign In
Statistics
Total Posts: 63
This Year: 0
This Month: 0
This Week: 0
Comments: 14
Themes
All Content © 2012, Guy Levin