Archive for July, 2011

Writing the Perfect Application

I have a confession to make: I’ve been working on the perfect application. How do I know it’s the perfect application? I know because it’s never done and there’s always “just one more thing” to refactor. And that, my friends, is a problem.

From a developer’s perspective there is no such thing as the perfect application. Users may say your application is the perfect application and help them get their job done faster and more efficiently. For you, though, you have seen what’s underneath the covers and if you’re like me, you’re always thinking of a better way that it can be written. You know where the dirty code is – the code that you want no one else to see, the code that you know could be cleaner, the code that could be made more efficient, and so on. The problem? Your time is limited and so is your customer’s patience.

I also have another confession to make: Despite what you might think based on some of the more technical posts on here, I’m not a pure code writing, hard core developer. I’m more of a consultant and systems integration professional. I do write code, and my code works pretty well, but most of the code I write is usually small snippets – such as plugins in CRM, which basically requires that I implement a single interface and write maybe a few hundred lines of code. I probably write my fair share of JavaScript code as well – again, usually simple snippets of code in something like the “onSave” event in Microsoft CRM.

The problem with these two confessions is that when I do have to write large amounts of code, I get stuck in what I call “code design paralysis”. It’s similar to analysis paralysis, but I am constantly overthinking how to design the code. Because I aspire to be more of a hard core, code writing junkie, I can take the simplest problem and ask an endless list of questions:

  • What design pattern can I use here?
  • What is the best way to structure my class hierarchy?
  • Should I not use inheritance and favor composition using interfaces?
  • Is this class too large and is it trying to do too much?
  • Do I have a clean separation of code, e.g., do I have a data access layer, a business layer, and a UI layer?
  • If I have created separate layers, have I intertwined them too much?
  • Is anyone even reading this anymore?

After you’ve defined the problem, have some sketches of the UI, understand the business rules, have a schema roughly defined and even a basic idea of how the code is going to look, you may find yourself where I do: asking the above questions over and over and get so stuck in code design paralysis that nothing gets done. That isn’t good for you or your customers. So what do you do to get your code done?

  • Start writing code to solve your business problem
  • As you code, be aware of different patterns and how they might help you
  • Study other people’s code – there are lots of open source projects out there that have great examples of different designs, patterns and practices that you can learn from
  • Find someone who knows more than you do and ask for their input on the project – this requires being willing to listen and accept constructive criticism
  • Refactor as needed, but don’t spend too much time refactoring to make the perfect application – sometimes you just need to get things working

The whole idea of cleaning up your code, using patterns and the like is an art. Nobody is an expert at anything on their first attempt, their second attempt, etc. A musicians first album may be a commercial success but you don’t see the hours, days, months and years they spent practicing, writing and performing to get to the point where they had that big hit. Your code is the same way – it takes time, effort and practice. The more you study and learn the better you’ll get at designing great applications.

The key to all this, though, is to stop reading and get coding!

I have a confession to make: I’ve been working on the perfect application. How do I know it’s the perfect application? I know because it’s never done and there’s always “just one more thing” to refactor. And that, my friends, is a problem.

From a developer’s perspective there is no such thing as the perfect application. Users may say your application is the perfect application and help them get their job done faster and more efficiently. For you, though, you have seen what’s underneath the covers and if you’re like me you’re always thinking of a better way that it can be written. You know where the dirty code is – the code that you want no one else to see, the code that you know could be cleaner, the code that could be made more efficient, and so on. The problem? Your time is limited and so is your customer’s patience.

I also have another confession to make: Despite what you might think based on some of the more technical posts on here, I’m not a pure code writing, hard core developer. I’m more of a consultant and systems integration professional. I do write code, and my code works pretty well, but most of the code I write is usually small snippets – such as plugins in CRM, which basically requires that I implement a single interface and write maybe a few hundred lines of code. I probably write my fair share of JavaScript code as well – again, usually simple snippets of code in something like the “onSave” event in Microsoft CRM.

The problem with these two confessions is that when I do have to write large amounts of code, I get stuck in what I call “code design paralysis”. It’s similar to analysis paralysis, but I am constantly overthinking how to design the code. Because I aspire to be more of a hard core, code writing junkie, I can take the simplest problem and ask an endless list of questions:

  • What design pattern can I use here?
  • What is the best way to structure my class hierarchy?
  • Should I not use inheritance and favor composition using interfaces?
  • Is this class too large and is it trying to do too much?
  • Do I have a clean separation of code, e.g., do I have a data access layer, a business layer, and a UI layer?
  • If I have created separate layers, have I intertwined them too much?
  • Is anyone even reading this anymore?
After you’ve defined the problem, have some sketches of the UI, understand the business rules, have a schema roughly defined and possibly even a rough idea of how the code is going to look, you may find yourself where I do: asking the above questions over and over and get so stuck in code design paralysis that nothing gets done. That isn’t good for you or your customers


Passing a method as a Func parameter simplifies your code

One of our older web applications in VB.NET has a page with several dependent dropdownlists that are designed to allow the user to choose various health benefits combinations. The rules for the dependencies vary and can be quite involved. To minimize database calls and to improve performance a caching layer was added. The process worked nicely, but included a lot of repetitive code to check the cache. For example, a check similar to the one in the method below had to be used each time an item was needed from the cache.

Cache Related Types


Public Function Apply() As IEnumerable(Of DropDownItem) Implements IFilter.Apply
    Items = CacheFactory.GetInstance.Get(Of IEnumerable(Of DropDownItem))(CacheKey)
    
    If Items Is Nothing Then
        Items = CommonBusiness.GetDropDownItems(GetSqlQuery(), GetParameters())
        CacheFactory.GetInstance.Insert(CacheKey, Items)
    End If
        
    Return Items
End Function

Attempt to get some data from the cache, if it was not found in the cache, load it from the database and add it to the cache.

Recently during an upgrade to .NET 4 I decided to refactor and apply the DRY principle. If the data was not in the cache, we need to get it from database (in this case), but the rules to get the data varies. So why not pass a delegate to retrieve the data we need if it’s not in the cache, that way the logic necessary to retrieve the data can be specified at runtime. That’s exactly what a Func is, a generic delegate type that represents a method that can be passed as a parameter without explicitly declaring a custom delegate. So in the ICache interface a new overloaded “GET” method was added that included a generic callback parameter with the type, Func(Of T).

Public Interface ICache
    Function [Get](Of T)(ByVal key As String) As T
    Function [Get](Of T)(ByVal key As String, ByRef callback As Func(Of T)) As T

    Sub Insert(ByVal key As String, ByVal value As Object)
    ' Other methods and overloads
End Interface

Here is an example of the implementation in my CacheManager class.

Public Function [Get](Of T)(ByVal key As String, ByRef callback As Func(Of T)) As T Implements ICache.Get
    Dim item As T = CType(cache.Get(key), T)

    If item Is Nothing Then
        item = callback()
        Insert(key, item)
    End If

    Return item
End Function

To call the Func, you can use a lambda expression, it’s basically an on the fly delegate. In VB, you create lambda expressions by using the Function or Sub keyword, just as you would a standard function or subroutine. However, lambda expressions are included in-line. Here’s the same Apply method listed earlier revised to use the overloaded Get with the Func parameter.

Public Function Apply() As IEnumerable(Of DropDownItem) Implements IFilter.Apply  
    Return CacheFactory.GetInstance.Get(Of IEnumerable(Of DropDownItem))(CacheKey, _
        Function() CommonBusiness.GetDropDownItems(GetSqlQuery(), GetParameters()))
End Function

Func and is its related type Action can help to reduce the amount of code you have to write and at the same time simplify the logic, making the code easier to read and maintain.





Below are C# versions of the code examples

public IEnumerable<DropDownItem> Apply()
{
	Items = CacheFactory.GetInstance.Get<IEnumerable<DropDownItem>>(CacheKey);

	if (Items == null) {
		Items = CommonBusiness.GetDropDownItems(GetSqlQuery(), GetParameters());
		CacheFactory.GetInstance.Insert(CacheKey, Items);
	}

	return Items;
}


public interface ICache
{
	T Get<T>(string key);
	T Get<T>(string key, Func<T> callback);

	void Insert(string key, object value);
	// Other Methods and overloads
}


public T Get<T>(string key, Func<T> callback)
{
	T item = (T)cache.Get(key);

	if (item == null) {
		item = callback();
		Insert(key, item);
	}

	return item;
}


public IEnumerable<DropDownItem> Apply()
{
	return CacheFactory.GetInstance.Get<IEnumerable<DropDownItem>>(CacheKey, 
		() => CommonBusiness.GetDropDownItems(GetSqlQuery(), GetParameters()));
}

Tags: , , , , ,


Microsoft CRM 2011: Update OData Example

Expanding upon Jeff Ballard’s recent post, Microsoft CRM 2011 oData Examples, the following is an example of how to use OData to update a record. Let’s say that we want to let the user not only see who the Account’s latest Contact is, but also allow them to update the Contact’s Job Title, E-mail, and Phone Number without needing to open up the Contact, itself. Start out by opening up the Account form and unchecking the “Field is read-only” option for the “Most Recent Contact”‘s E-mail, Job Title, and Phone Number fields, then we’ll jump right to the code (which was shamelessly pared down from the example in this fantastic MS TechNet article).

Open up the form properties and add json2.js as a new JavaScript Web Resource (for its handy “stringify” function), then open up the new_oDataExample library. First, modify the “requestComplete” function so that we have a new condition that looks for a queryName of “MostRecent_Save” and add code to populate an object with the four “Recent Contact” fields. We’ll be passing that object to the “updateContact” function, along with the Contact’s Guid.

function requestComplete(request, queryName) {
    /*  A request.readyState of 4 means the request is complete. If 
        it's complete and the status is 200 (OK), then we can assign the results
        of the call to our controls on the form.*/
    if (request.readyState == 4 && request.status == 200) {
        var json = $.parseJSON(request.responseText);
        if ( (json != undefined) && (json.d != undefined) && (json.d.results != undefined) && (json.d.results[0] != null) ) {
            json = json.d.results[0];
            // Note that the way things are set up, it's possible to have more
            // than one "Support Contact" returned but I'm hard coding the results
            // to return the first contact only.
            if (queryName == "MostRecent") {
                xp.getAttribute("new_mostrecentfullname").setValue(json.FullName);
                xp.getAttribute("new_mostrecentphone").setValue(json.Telephone1);
                xp.getAttribute("new_mostrecentemail").setValue(json.EMailAddress1);
                xp.getAttribute("new_mostrecenttitle").setValue(json.JobTitle);
                // As an aside (the field below doesn't exist), when placing values 
                // into a numeric field, you will need to use the javascript 
                // function parseFloat to prevent CRM type errors.
                //xp.getAttribute("new_numericrank").setValue(parseFloat(json.new_NumericRank));
            } else if (queryName == "SupportContact") {
                xp.getAttribute("new_supportfullname").setValue(json.FullName);
                xp.getAttribute("new_supportphone").setValue(json.Telephone1);
                xp.getAttribute("new_supportemail").setValue(json.EMailAddress1);
                xp.getAttribute("new_supporttitle").setValue(json.JobTitle);
            } else if (queryName == "MostRecent_Save") {
                var changes = new Object();
                changes.FullName = xp.getAttribute("new_mostrecentfullname").getValue();
                changes.Telephone1 = xp.getAttribute("new_mostrecentphone").getValue();
                changes.EMailAddress1= xp.getAttribute("new_mostrecentemail").getValue();
                changes.JobTitle= xp.getAttribute("new_mostrecenttitle").getValue();

                updateContact(json.ContactId, changes);
            }
        }
    }
}

Now go ahead and add the “onSave” function to the library. “onSave” will be building a query that’s very similar to the “Most Recent Contact” query that’s used to populate those fields, only we’re just interested in the Guid this time. It calls “getContact” and passes along the “MostRecent_Save” queryName that we added a condition for in “requestComplete”.

function onSave(context) {
    var accountId = xp.data.entity.getId();
    
    // Since we're not saving the most recent Contact's Guid anywhere on the page, request it.
    var mostRecentQuery = "/XRMServices/2011/organizationData.svc/ContactSet?$select=ContactId&$top=1&$orderby=CreatedOn desc&$filter=ParentCustomerId/Id eq guid'" + accountId + "'";
    getContact(mostRecentQuery, "MostRecent_Save");

}

Finally, add the “updateContact” function. This will be using the Contact Guid to merge the changes in the object we populated in “requestComplete” with the Contact’s record.

function updateContact(id, contactObject) {

  //Parse the entity object into JSON
  var jsonEntity = window.JSON.stringify(contactObject);

  //Asynchronous AJAX function to Update a CRM record using OData
 $.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    data: jsonEntity,
    url: Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/ContactSet(guid'" + id + "')",
    beforeSend: function (XMLHttpRequest) {
      //Specifying this header ensures that the results will be returned as JSON.             
      XMLHttpRequest.setRequestHeader("Accept", "application/json");

      //Specify the HTTP method MERGE to update just the changes you are submitting.             
      XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
    }
  });
}

Add a reference to the “onSave” function in the Form onSave Event Handler subgrid and you’re ready to go! After publishing the changes, you’ll be able to update the most recent Contact’s information from the related Account entity. Jeff’s original exported solution has been updated with these changes and is available for download here!

Tags: , ,