Sunday, November 14, 2010

Regenerating customized code

Suppose we define the Customer object as follows:

<object name="Customer">
<property name="name" />
</object>


Based on this knowledge, our code generator emits the following snippet:

public void SaveCustomer(string name)
{
Customer customer = new Customer();
customer.Name = name;
customer.Save();
}


Since our application needs the Customer's name to be capitalized, we customize the code as follows. Let's name this version V1.

public void SaveCustomer(string name)
{
Customer customer = new Customer();
customer.Name = name.ToUpper();
customer.Save();
}


We later add an Address property to the Customer object:

<object name="Customer">
<property name="name" />
<property name="address" />
</object>


This time, our code generator emits the following snippet.
Let's name this version V2.

public void SaveCustomer(string name, string address)
{
Customer customer = new Customer();
customer.Name = name;
customer.Address = address;
customer.Save();
};


The following strategy highlights how to integrate the new code, while preserving the customizations that were made. This will be accomplished by merging the customized version V1 with the regenerated version V2.

The two following conflicts will be reported:

V1 public void SaveCustomer(string name)
V2 public void SaveCustomer(string name, string address)

V1 customer.Name = name.ToUpper();
V2 customer.Name = name;


Knowing that we are adding the Address property, the first conflict is easily resolved in favor of the regenerated V2. In contrast, the new property should not impact the Customer's name, so the second conflict is resolved in favor of the customized V1.

A diff between version V1 and the merged code will then confirm that the new code was correctly integrated:

- public void SaveCustomer(string name)
+ public void SaveCustomer(string name, string address)
= {
= Customer customer = new Customer();
= customer.Name = name.ToUpper();
+ customer.Address = address;
= customer.Save();
= }

Sunday, June 13, 2010

Entity Framework Querying 101

// The database tables are represented by object sets.
// These provide the basic CRUD operations on the table.
ObjectSet<Contact> objectSet = objectContext.Contacts;

// The object sets are themselves object queries.
// These provide support for queries written in Entity SQL.
ObjectQuery<Contact> objectQuery1 = objectContext.Contacts;

ObjectQuery<Contact> objectQuery2 = objectContext.Contacts
.Where("it.FirstName = 'Mathieu'");

ObjectQuery<Contact> objectQuery3 = objectContext.CreateQuery<Contact>(
"SELECT VALUE it FROM EntityContainer.Contacts AS it " +
"WHERE it.FirstName = @firstName");

objectQuery3.Parameters.Add(new ObjectParameter(
"firstName", "Mathieu"));

// The object queries finally implement IQueriable.
// This enables the use of Linq to Entities queries.
IQueryable<Contact> iQueryable1 = objectContext.Contacts;

IQueryable<Contact> iQueryable2 = objectContext.Contacts
.Where(contact => contact.FirstName == "Mathieu");

// All these techniques are equivalent ways to define a query,
// which won't actually be executed before it is enumerated.

Saturday, February 6, 2010

Wizards in a stateless web

Maintaining the information gathered throughout the steps of a wizard can be challenging for a website. We will here explore an approach which relies on the back end database.

Suppose our website provides a wizard for creating customers. The first step would be responsible for gathering the customer's name. When posted, the first form will be sent to the BeginCustomer service, which will insert a row in the PendingCustomer table, returning the generated ID.

The second step would be responsible for gathering the customer's address. When displayed, the second form will invoke the GetNewCustomerAddress service with the previously generated PendingCustomerID. Given that no address has yet been entered, it will initially appear empty.

When posted, the second form will invoke the SetNewCustomerAddress service with the PendingCustomerID. The service will insert a row in the PendingCustomerAddress table.

Should the second step be redisplayed through the back button, the GetNewCustomerAddress service will be reinvoked. This time, the second step will display the previously entered address. And should the second step be reposted, the SetNewCustomerAddress service will overwrite the values in the PendingCustomerAddress table.

Finally, when the wizard is completed, the final form post will invoke the CommitNewCustomer service. The service will validate the information saved in the pending tables, transfer this information to the real tables, and delete it from the pending tables. From then on, the PendingCustomerID will be invalid, making it impossible to get back to the wizard steps.

Saturday, August 8, 2009

One URL, one HTTP verb

Any URL that accepts HTTP POSTs should not render an HTML page. It should only perform an action on the web application, such as creating a new order, or updating a customer's record.

Displaying a page at the same time would only cause confusion for the web site's user. I really like this page, but it was displayed because I updated this customer from Chicago. What if I want to redisplay the same page later, will I need to update the customer one more?

And what about the dreaded message box when the refresh button is used: To display the webpage again, Internet Explorer needs to resend the information you've previously submitted. Retry, Cancel?

To avoid these issues, an HTTP POST should be responded to by a redirection inviting the browser to GET another URL. This gives the web site's user a clear address to return to should he like the page displayed as a result of his actions.

This implies that when we configure the routing for a given URL, we really should assign it only one of the HTTP verbs. Either the URL will accept HTTP GETs and display an HTML page, either it will accept HTTP POSTs and perform a redirection.

Tuesday, August 4, 2009

Validating Operation, Not Entities

Suppose that our system manages a list of customers, which is used by both the accounting and the shipping departments. As we strive to implement validation logic in our application, we are likely to consider the following solution.

We could define a CustomerEntity class, which could implement an IsValid method that would check the integrity of the whole entity. We would then refuse to save a customer for which this test would fail. There are several drawbacks to this approach, though.

First, let's consider a customer is valid only if the total of his pending orders is less that his allowed credit, and if he has paid his last invoices. Checking these rules requires a lot of data to be retrieved from the database, which induces a high cost every time we save a customer.

Also, the user saving a customer may not know how to resolve such a validation error. For example, let's imagine the shipping department is left unable to change a customer's address because of unpaid invoices. Since this concern is outside of the shipping department's concerns, they should be allowed to proceed, reassured in the knowledge that the invoice issues are correctly handled by the accounting department.

The validation strategy we retain is to enforce the rules at the operation level. Only the customer data concerned by a specific operation needs to be validated.

For example, the NewOrder operation would perform the costly check about the payment of the previous invoices, because the business would otherwise refuse the order. An UnpaidInvoices error code could then be returned, knowing that it will be meaningful to the caller.

On the other hand, the ChangeAddress operation would know nothing about this rule, since an address change is always permitted. This operation could then avoid the costly but unrelated validations.

Wednesday, July 1, 2009

Naming Conventions

Here are simple rules to provide namespaces and names to the classes defined within an application. To illustrate these rules, let us consider a DataAccessLayer composed of a set of DataAccessor classes. We could therefore be working with the following classes:

A first DataAccessor managing Customers
A second DataAccessor managing Products
A third DataAccessor managing Orders

We here have a single concept, the DataAccessor, applied to multiple contexts, being the Customers, Products and Orders. As a rule, we should provide a namespace for each context, and our classes should be named with the context’s name, suffixed by the concept’s name.

This would lead to the following naming hierarchy:

DataAccessLayer
  Customer
    CustomerDataAccessor
  Product
    ProductDataAccessor
  Order
    OrderDataAccessor

Such a naming convention allows the addition of new contexts through new namespaces, and the addition of new concepts within the existing namespaces.

Let us suppose the DataAccessors are designed to work with DataRow classes, and suppose furthermore that our application now needs to manage Shipments. We could adjust our naming hierarchy as such:

DataAccessLayer
  Customer
    CustomerDataAccessor
    CustomerDataRow
  Product
    ProductDataAccessor
    ProductDataRow
  Order
    OrderDataAccessor
    OrderDataRow
  Shipment
    ShipmentDataAccessor
    ShipmentDataRow

Also, this naming convention prevents name clashes at different levels. First, the every namespace differ from all of the class names. That is, Customer differs from both CustomerDataAccessor and CustomerDataRow. Secondly, name clashes are also prevented in between layers.

Let us suppose a BusinessLogicLayer managing Customers through the concepts of Requests and Responses. We could then be facing this second naming hierarchy:

BusinessLogicLayer
  GetCustomer
    GetCustomerRequest
    GetCustomerResponse

Even though both layers work with the Customer context, name clashes would be prevented, as illustrated by the following code snippet:

getCustomerResponse.Name = customerDataRow.Name;
getCustomerResponse.Age = customerDataRow.Age;

Finally, this protection can be extended to nested classes with the following rule. Let us suppose the GetCustomerResponse class requires two nested classes, one for an Address, and another for a Customer. Since these classes are elements of the Response concept, their name should be suffixed with ResponseElement. This would lead the following naming hierarchy within the GetCustomerResponse class:

GetCustomerResponse
  AddressResponseElement
  CustomerResponseElement

Given this rule, name clashes are once again prevented as illustrated below:

customerResponseElement.Name = customerDataRow.Name;
customerResponseElement.Age = customerDataRow.Age;
getCustomerResponse.Customer = customerResponseElement;

Sunday, February 15, 2009

Making Good Use of the UpdatePanel

Let's first review the basic interaction between a browser and a web server. First, responding to an HTTP GET request, the server returns an HTML page to be displayed by the browser. From there, the user can interact with the page, causing an HTTP POST of the page's FORM to be sent back to the server.

A traditional approach used by ASP.NET developers is to initialize the page's content upon receiving the HTTP GET request, and to skip this costly step when the page is postbacked:

/// <summary>
/// Occurs when the page is loaded.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
// Do not consider postbacks.
if (this.IsPostBack)
{
return;
}
// Initialize the page's data.
this.DisplayAnimals();
this.DisplayPlaces();
}

If the page needs to be updated following an HTTP POST, only the required part is updated, thus minimizing the usage of resources on the server:

/// <summary>
/// Occurs when the Animals buttons is clicked.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnAnimals_Click(object sender, EventArgs e)
{
// Update only the required page's data.
this.DisplayAnimals();
}

The strategy described above makes no use of Ajax, yet it does partial page rendering. Following an HTTP POST, only the parts of the page that need to be updated are rendered, while the rest of the page is kept as initialized by the ViewState mechanism.

So we have a solution that is nice to the server resources, but not as so on the bandwidth. First, the server respond to every HTTP POST with the full HTML of the page, even if we have changed only part of it. Second, the ViewState mechanism bloats the page's HTML and only aggravates the situation.

The advent of ASP.NET Ajax introduces the concept of partial page updates. While the web server still renders the whole page to respond to an HTTP POST request, only a part of the page's HTML can now be returned. This HTML is then dynamically replaced in the browser page by clever client scripts.

Combined with our partial page rendering strategy, the UpdatePanel provides a strong solution to prevent page refreshes in the browser. First, only the required HTML is rendered by the server, and then, only the rendered HTML is sent back to the browser.