Wednesday, February 24, 2010

Sydney's ALT.NET User Group Gathering

Yesterday was my first time at the ALT.NET User Group and it was a lot of fun.

Apart from Richard Banks (who I'd worked with before) it was a sea of new faces, which is cool as one of the reasons I wanted to go was to get to know other people in the industry.

So for those who haven't been before, here's my little run down on the night.

The night started at 6pm so people were rocking up from around 5:30.

Not know anyone, most of my time was walking around shaking hands and saying, "Hi my name's Matthew. How you doing?". There seemed to be a great variety of people with even a C++ developer amoungst us. :)

Richard kicked things off with general question to everyone about anything cool they'd seen/read/done etc, then we continued with two presentations, one from James Crisp on Automated Builds and another by Romain Prieto on Automated Deployments.

Automated Builds
James started off his talk by implying that all the xml based build systems were crap, and introduced nRake.
nRake removes the dependency on a huge amount of xml configuration and introduces Ruby's OO scripting in-order to programmatically generate a build. Very interesting.

Automated Deployments
Next came Romain who introduced the concept of automating the deployments. Romain has put together a little tool he's called psDeploy (which he informs us he'll be putting up on Github soon), which is a library of cmdlets to assist with the deployment of applications. He highlighted how this tool works well with TFSDeployer and psake.

Besides the talks being enjoyable, the sarcasm was great.

Overall an enjoyable and interesting evening which I'd recommend.

Next month => hands-on-lab in a coding dojo.

Enjoy.

[Edit] psDeploy is now up on GitHub.

Friday, February 12, 2010

Great Scrum Resources

I just read a nice little post on Richard's Braindump regarding a new Professional Scrum Developer Course being offered at Scrum.org. Rather parrot what Richard said go read his post.

Anyway, while having a look through the site I came across some awesome Scrum Instructional Videos. Even if you've worked with Scrum, or maybe you think you've worked with Scrum, these are worth a look.

Enjoy!

Thursday, February 11, 2010

Wrapping WCF Services in a Using Statement

Considering that the WCF Services I've created for my budget application are the first I've written, I hadn't actually given much thought into how I would actually call them.

Here's what I came up with!

IMthService svc = new MthServiceClient();
svc.Save( newMonthObject );

Of course, what I discovered was that my services were timing out after the sixth call (not sure why it was six as the default is ten). Any how, I quickly discovered that while the service that's is written doesn't directly inherit from IDisposable, the service client does. So in effect my code was not disposing of the service client properly. So how do I dispose of the client considering that the Dispose method is private? Easy, call Close or Abort. Duh!

There are various posts floating around that instruct on wrapping your service call in a try catch, but I didn't want to write try{...}catch{...} time and time again.

It was at this time that I recalled reading a nice post about a common WCF exception message that provided a nice little solution to my problem. Thanks Damien McGivern for coming up with the following solution.

public static void Using<TService>( Action<TService> action )
  where TService : ICommunicationObject, IDisposable, new()
{
  var service = new TService();
  bool success = false;
  try
  {
    action( service );
    if ( service.State != CommunicationState.Faulted )
    {
      service.Close();
      success = true;
    }
  }
  finally
  {
    if ( !success )
    {
      service.Abort();
    }
  }
}

So now I can call my services like this...
WCFHelper.Using<MthCategoryServiceClient>
  ( svc => svc.Save( mc ) );
and
WCFHelper.Using<MthCategoryServiceClient>
  ( svc => mthCategories = svc.GetByMonth( mthId ) );

Enjoy

Wednesday, February 10, 2010

Handling AJAX requests with ExtJs GridPanel and jQuery Consistently

In my previous post, An Implementation of the ExtJs GridPanel, I demonstrated how you could implement a GridPanel using the ExtJs framework, and mentioned the writer object that creates default CRUD AJAX calls.

This is handy and quite easy to handle server side, as the writer object injects a hidden form element (id='xaction') into the DOM.

string action = Request.Form["xaction"];
if ( !string.IsNullOrEmpty( action ) )
{
  switch ( action )
  {
    case "create":
      CreatCategory();
      break;
    case "update":
      UpdateCategory();
      break;
    case "destroy":
      DeleteCategory();
      break;
    default:
      ListCategory();
      break;
  }
}

However, on another page I didn't want to submit a request per edit or per row edit, but wanted to submit a request in bulk. So how did I go about that?


Firstly, I removed the writer object from the store object as below...
var mcStore = new Ext.data.Store({
  id: 'dsMthCategories',
  proxy: mcProxy,
  reader: mcReader,
  baseParams: { xaction: "LISTING" }, // *** take note
  //writer: mcWriter,    // <-- remove the Writer object
  listeners: {
    'beforeload': function(store, options) {
      options.params['mthId'] = mthid;
    }
  }
});
Next I added the following in the handler of the Update button...
var data = [];
Ext.each(mcGrid.getStore().getModifiedRecords(), function(record) {
 data.push(record.data);
});

$.ajax({
  type: "POST",
  url: 'Data/MthCategories.aspx?xaction=batchupdate', // *** take note
  data: JSON.stringify(data),
  contentType: "application/json;",
  dataType: "json",
  success: function(msg) {
    mcGrid.store.load();
  },
  error: function(msg) {
    alert('An error occured during the update.');
  }
});

Two things to note about the above code is that the default action of the store is to add the value "LISTING" to the injected xaction form element and in the jquery ajax function call I've added xaction to the querystring.

This enables the ability to utilise the HttpRequest.Params property, which picks up both Form and QueryString items.
string action = Request.Params["xaction"];
if ( !string.IsNullOrEmpty( action ) )
{
  switch ( action )
  {
    case "batchupdate":
      BatchUpdate();
      break;
    default:
      ListMonthCategories();
      break;
    }
}

And there you have it.

Enjoy!

Sunday, February 7, 2010

An Implementation of the ExtJs GridPanel

So in my last post I demonstrated how I put together some an ExtJs TabPanel. Now this is not the only way to do this, but it is one way. Now I'm going to take you through how I put together an ExtJs GridPanel.

The html is remarkably simple.

<div id="CategoriesContainer">
    <div class="TabContent"></div>
</div>

Next comes the more complex part of the implementation :)

$(document).ready(function() {

 $.namespace("category", {
  inherited: true,

  InitialiseControl: function() {
   $.fn.category.LoadCategoryGrid();
  },

  LoadCategoryGrid: function() {

   var tabContent = $("#CategoriesContainer").children(".TabContent");

   var proxy = new Ext.data.HttpProxy({
    url: 'Data/Categories.aspx'
   });

   var reader = new Ext.data.JsonReader({
    root: 'Data',
    totalProperty: 'Count',
    idProperty: 'CategoryId',
    fields: [
     { name: 'CategoryId', type: 'int' },
     { name: 'CategoryName', type: 'string', allowBlank: false },
     { name: 'BudgetAmount', type: 'float', allowBlank: false },
     { name: 'IsActive', type: 'boolean' },
     { name: 'Timestamp', type: 'date', dateFormat: 'M$' },
     { name: 'Version', type: 'auto' }
    ]
   });

   var writer = new Ext.data.JsonWriter({
    encode: true,   // <-- don't return encoded JSON -- causes Ext.Ajax#request to send data using 
        // jsonData config rather than HTTP params
    writeAllFields: true
   });

   var store = new Ext.data.Store({
    id: 'dsCategores',
    proxy: proxy,
    reader: reader,
    writer: writer,
    listeners: {
     'update': function(store, record, operation) {
      store.commitChanges();
     },
     'remove': function(store, record, index) {
      store.commitChanges();
     }
    }
   });

   var colModel = new Ext.grid.ColumnModel({
    defaults: {
     sortable: true
    },
    columns: [
     {header: 'Name', dataIndex: 'CategoryName', editor: new Ext.form.TextField({}) },
     { header: 'Budget Amount', dataIndex: 'BudgetAmount', xtype: 'numbercolumn', format: '$0,0.00', align: 'right', editor: new Ext.form.NumberField({}) },
     { header: 'Active', dataIndex: 'IsActive', xtype: 'booleancolumn', trueText: 'Yes', falseText: 'No', align: 'center', editor: new Ext.form.Checkbox({}) }
    ]
   });

   // use RowEditor for editing
   var editor = new Ext.ux.grid.RowEditor({
    saveText: 'Update'
   });

   var grid = new Ext.grid.GridPanel({
    iconCls: 'icon-grid',
    frame: true,
    title: 'Categories',
    loadMask: true,
    autoScroll: true,
    height: 300,
    store: store,
    plugins: [editor],
    colModel: colModel,
    tbar: [{
     text: 'Add',
     iconCls: 'silk-add',
     handler: function(btn, ev) {
      var u = new grid.store.recordType({
       Description: '',
       Amount: '',
       IsActive: true
      });
      editor.stopEditing();
      grid.store.insert(0, u);
      editor.startEditing(0);
     }
    }, '-', '->', '-', {
     text: 'refresh',
     iconCls: 'silk-table-refresh',
     handler: function() {
      grid.store.load();
     }
    }],
    viewConfig: {
     forceFit: true
    }
   });

   grid.render(tabContent[0]);

   store.load();
  }
 });
});

So what's actually going on here?

Firstly,
$(document).ready(function() {
  $.namespace("category", {
    inherited: true,

    InitialiseControl: function() {
      $.fn.category.LoadCategoryGrid();
    },
Here I am using a jquery namespace pluging to create (oddly enough!) a namespace for the javascript for this particular control (or tab). The line inherited: true allows you to interact with function parameters as normal, rather than referring to them as params[0], params[1] etc.

The rest of the javascript is fairly standard ExtJs syntax and extensive definitions can be found at the ExtJs API, but in short I follow these steps when setting up a grid:

  1. Create a proxy object and set the URL it should post to;
  2. Create a reader object. In my case it's a JsonReader and I set the properties that allow the object to interact with the returned Json data;
  3. Create a writer object. This creates default CRUD actions for you;
  4. Create a store object and set up listeners for update and delete calls (mind you I'm not actually deleting anything);
  5. Create a column model for the grid. This maps the fields from the reader to the columns;
  6. Create a RowEditor object. This is a plug-in that gets applied to the grid and can be downloaded from an ExtJs example Grid with RowEditor;
  7. Create the grid;
  8. Get the grid to render to a particular DOM element;
  9. And lastly load the store object;

Next up will be a short post on how to deal with the Ajax requests server side in a C# environment.

Enjoy!