posts - 28 , comments - 23 , trackbacks - 0

My Links

News

Twitter












Tag Cloud

Archives

Sunday, March 31, 2013

Free books from Syncfusion

Everybody has a slightly different learning style that works best for them - often with different forms of content working best at various stages in their learning.  I've always been an avid reader and tend to "index" most everything that I read for reference later when it becomes important.  That being said, the first thing I do when getting ready to learn a new tool or technology is almost invariably to look for something (or many somethings) that has been written on the topic.  That's followed closely by getting my hands on the tool and video/audio presentations tend to follow way behind.  Over the years I have spent a lot of money on books, so I am always excited to learn about new sources of reasonably priced or free books that actually offer valuable learning.

Recently my attention was brought to the Succinctly series from Syncfusion.  This series, available at http://www.syncfusion.com/resources/techportal/ebooks, is a free collection of eBooks that give a brief coverage of the some of the most important aspects when getting up to speed on a new tool or technology.  The books are mostly around 100 pages each and are intended to get straight to the point.

Last week I read my first Succinctly series book, Knockout.js Succinctly.  I found the book to be pleasantly well done and finished reading it feeling well armed to jump right in and start doing some MVVM development in HTML/JS (I'm an admitted XAML snob when it comes to MVVM development).

Having recently purchased my first Mac, I think the next stop for me in the Succinctly series will be Objective-C Succinctly.

If you find yourself learning best from reading like I do (or even if you just like to read sometimes), I highly recommend that you give the Succinctly series a read.

Posted On Sunday, March 31, 2013 4:43 PM | Comments (1) |

Wednesday, November 7, 2012

Where's the source code?

UPDATE: I have just received confirmation that the source code is now available from the book's product page on the Apress website (http://www.apress.com/9781430245667).  Thanks to everyone that waited patiently for this to be made available.

I've been contacted by several people through this blog asking about the missing source code for the "Beginning Windows 8 Application Development - XAML Edition" book (the book is available at http://www.amazon.com/gp/product/1430245662/http://www.amazon.com/gp/product/1430245662/) and wanted to share this with others who may have come to this blog looking for it but may not have communicated with me.  The publisher (Apress) does know that the source code is not posted on the book's product page and will be correcting it.  Apress is located in New York City and things were slowed down a little bit last week due to the storm, but I've been assured they will be correcting the product page as soon as they can.  Thanks to everyone who has bought the book and I especially appreciate your patience.

Posted On Wednesday, November 7, 2012 6:19 AM | Comments (1) |

Thursday, October 18, 2012

Using Sitecore RenderingContext Parameters as MVC controller action arguments

I have been working with the Technical Preview of Sitecore 6.6 on a project and have been for the most part happy with the way that Sitecore (which truly is an MVC implementation unto itself) has been expanded to support ASP.NET MVC. That said, getting up to speed with the combined platform has not been entirely without stumbles and today I want to share one area where Sitecore could have really made things shine from the "it just works" perspective.

A couple days ago I was asked by a colleague about the usage of the "Parameters" field that is defined on Sitecore's Controller Rendering data template. Based on the standard way that Sitecore handles a field named Parameters, I was able to deduce that the field expected key/value pairs separated by the "&" character, but beyond that I wasn't sure and didn't see anything from a documentation perspective to guide me, so it was time to dig and find out where the data in the field was made available. My first thought was that it would be really nice if Sitecore handled the parameters in this field consistently with the way that ASP.NET MVC handles the various parameter collections on the HttpRequest object and automatically maps them to parameters of the action method executing. Being the hopeful sort, I configured a name/value pair on one of my renderings, added a parameter with matching name to the controller action and fired up the bugger to see... that the parameter was not populated.

Having established that the field's value was not going to be presented to me the way that I had hoped it would, the next assumption that I would work on was that Sitecore would handle this field similar to how they handle other similar data and would plug it into some ambient object that I could reference from within the controller method. After a considerable amount of guessing, testing, and cracking code open with Redgate's Reflector (a must-have companion to Sitecore documentation), I found that the most direct way to access the parameter was through the ambient RenderingContext object using code similar to:

string myArgument = string.Empty;
var rc = Sitecore.Mvc.Presentation.RenderingContext.CurrentOrNull;
if (rc != null)
{
    var parms = rc.Rendering.Parameters;
    myArgument = parms["myArgument"];
}

At this point, we know how this field is used out of the box from Sitecore and can provide information from Sitecore's Content Editor that will be available when the controller action is executing, but it feels a little dirty. In order to properly test the action method I would have to do a lot of setup work and possible use an isolation framework such as Pex and Moles to get at a value that my action method is dependent upon. Notice I said that my method is dependent upon the value but in order to meet that dependency I've accepted another dependency upon Sitecore's RenderingContext.  I'm a big believer in, when

possible, ensuring that any piece of code explicitly advertises dependencies using the method signature, so I found myself still wanting this to work the same as if the parameters were in the request route, querystring, or form by being able to add a myArgument parameter to the action method and have this

parameter populated by the framework. Lucky for us, the ASP.NET MVC framework is extremely flexible and provides some easy to grok and use extensibility points.

ASP.NET MVC is able to provide information from the request as input parameters to controller actions because it uses objects which implement an interface called IValueProvider and have been registered to service the application. The most basic statement of responsibility for an IValueProvider implementation is "I know about some data which is indexed by key. If you hand me the key for a piece of data that I know about I give you that data". When preparing to invoke a controller action, the framework queries registered IValueProvider implementations with the name of each method argument to see if the ValueProvider can supply a value for the parameter.

(the rest of this post will assume you're working along and make a lot more sense if you do)

Let's pull Sitecore out of the equation for a second to simplify things and create an extremely simple IValueProvider implementation. For this example, I first create a new ASP.NET MVC3 project in Visual Studio, selecting "Internet Application" and otherwise taking defaults (I'm assuming that anyone reading this far in the post either already knows how to do this or will need to take a quick run through one of

the many available basic MVC tutorials such as the MVC Music Store). Once the new project is created, go to the Index action of HomeController.  This action sets a Message property on the ViewBag to "Welcome to ASP.NET MVC!" and invokes the View, which has been coded to display the Message. For our example, we will remove the hard coded message from this controller (although we'll leave it just as hard coded somewhere else - this is sample code).

For the first step in our exercise, add a string parameter to the Index action method called welcomeMessage and use the value of this argument to set the ViewBag.Message property. The updated Index action should look like:

public ActionResult Index(string welcomeMessage)
{
    ViewBag.Message = welcomeMessage;
    return View();
}

This represents the entirety of the change that you will make to either the controller or view.  If you run the application now, the home page will display and no message will be presented to the user because no value was supplied to the Action method. Let's now write a ValueProvider to ensure this parameter gets populated. We'll start by creating a new class called StaticValueProvider. When the class is created, we'll update the using statements to ensure that they include the following:

using System.Collections.Specialized;
using System.Globalization;
using System.Web.Mvc;

With the appropriate using statements in place, we'll update the StaticValueProvider class to implement the IValueProvider interface. The System.Web.Mvc library already contains a pretty flexible dictionary-like implementation called NameValueCollectionValueProvider, so we'll just wrap that and let it do most of the real work for us. The completed class looks like:

public class StaticValueProvider : IValueProvider
{
    private NameValueCollectionValueProvider _wrappedProvider;

    public StaticValueProvider(ControllerContext controllerContext)
    {
        var parameters = new NameValueCollection();
        parameters.Add("welcomeMessage", "Hello from the value provider!");
        _wrappedProvider = new NameValueCollectionValueProvider(parameters, CultureInfo.InvariantCulture);
    }

    public bool ContainsPrefix(string prefix)
    {
        return _wrappedProvider.ContainsPrefix(prefix);
    }

    public ValueProviderResult GetValue(string key)
    {
        return _wrappedProvider.GetValue(key);
    }
}

Notice that the only entry in the collection matches the name of the argument to our HomeController's Index action.  This is the important "secret sauce" that will make things work.

We've got our new value provider now, but that's not quite enough to be finished. Mvc obtains IValueProvider instances using factories that are registered when the application starts up. These factories extend the abstract ValueProviderFactory class by initializing and returning the appropriate implementation of IValueProvider from the GetValueProvider method. While I wouldn't do so in production code, for the sake of this example, I'm going to add the following class definition within the StaticValueProvider.cs source file:

public class StaticValueProviderFactory : ValueProviderFactory
{
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        return new StaticValueProvider(controllerContext);
    }
}

Now that we have a factory, we can register it by adding the following line to the end of the Application_Start method in Global.asax.cs:

ValueProviderFactories.Factories.Add(new StaticValueProviderFactory());

If you've done everything right to this point, you should be able to run the application and be presented with the home page reading "Hello from the value provider!".

Now that you have the basics of the IValueProvider down, you have everything you need to enhance your Sitecore MVC implementation by adding an IValueProvider that exposes values from the ambient RenderingContext's Parameters property. I'll provide the code for the IValueProvider implementation (which should look VERY familiar) and you can use the work we've already done as a reference to create and register the factory:

public class RenderingContextValueProvider : IValueProvider
{
    private NameValueCollectionValueProvider _wrappedProvider = null;

    public RenderingContextValueProvider(ControllerContext controllerContext)
    {
        var collection = new NameValueCollection();
        var rc = RenderingContext.CurrentOrNull;
        if (rc != null && rc.Rendering != null)
        {
            foreach(var parameter in rc.Rendering.Parameters)
            {
                collection.Add(parameter.Key, parameter.Value);
            }
        }

        _wrappedProvider = new NameValueCollectionValueProvider(collection, CultureInfo.InvariantCulture);     
    }

    public bool ContainsPrefix(string prefix)
    {
        return _wrappedProvider.ContainsPrefix(prefix);
    }

    public ValueProviderResult GetValue(string key)
    {
        return _wrappedProvider.GetValue(key);
    }
}

In this post I've discussed the MVC IValueProvider used to map data to controller action method arguments and how this can be integrated into your Sitecore 6.6 MVC solution.

Posted On Thursday, October 18, 2012 8:33 AM | Comments (3) |

Tuesday, October 9, 2012

When is my View too smart?

In this posting, I will discuss the motivation behind keeping View code as thin as possible when using patterns such as MVC, MVVM, and MVP.  Once the motivation is identified, I will examine some ways to determine whether a View contains logic that belongs in another part of the application.  While the concepts that I will discuss are applicable to most any pattern which favors a thin View, any concrete examples that I present will center on ASP.NET MVC.

Design patterns that include a Model, a View, and other components such as a Controller, ViewModel, or Presenter are not new to application development.  These patterns have, in fact, been around since the early days of building applications with graphical interfaces.  The reason that these patterns emerged is simple – the code running closest to the user tends to be littered with logic and library calls that center around implementation details of showing and manipulating user interface widgets and when this type of code is interspersed with application domain logic it becomes difficult to understand and much more difficult to adequately test.  By removing domain logic from the View, we ensure that the View has a single responsibility of drawing the screen which, in turn, makes our application easier to understand and maintain.

I was recently asked to take a look at an ASP.NET MVC View because the developer reviewing it thought that it possibly had too much going on in the view.  I looked at the .CSHTML file and the first thing that occurred to me was that it began with 40 lines of code declaring member variables and performing the necessary calculations to populate these variables, which were later either output directly to the page or used to control some conditional rendering action (such as adding a class name to an HTML element or not rendering another element at all).  This exhibited both of what I consider the primary heuristics (or code smells) indicating that the View is too smart:

  • Member variables – in general, variables in View code are an indication that the Model to which the View is being bound is not sufficient for the needs of the View and that the View has had to augment that Model.  Notable exceptions to this guideline include variables used to hold information specifically related to rendering (such as a dynamically determined CSS class name or the depth within a recursive structure for indentation purposes) and variables which are used to facilitate looping through collections while binding.
  • Arithmetic – as with member variables, the presence of arithmetic operators within View code are an indication that the Model servicing the View is insufficient for its needs.  For example, if the Model represents a line item in a sales order, it might seem perfectly natural to “normalize” the Model by storing the quantity and unit price in the Model and multiply these within the View to show the line total.  While this does seem natural, it introduces a business rule to the View code and makes it impossible to test that the rounding of the result meets the requirement of the business without executing the View.  Within View code, arithmetic should only be used for activities such as incrementing loop counters and calculating element widths.

In addition to the two characteristics of a “Smart View” that I’ve discussed already, this View also exhibited another heuristic that commonly indicates to me the need to refactor a View and make it a bit less smart.  That characteristic is the existence of Boolean logic that either does not work directly with properties of the Model or works with too many properties of the Model.  Consider the following code and consider how logic that does not work directly with properties of the Model is just another form of the “member variable” heuristic covered earlier:

@if(DateTime.Now.Hour < 12) {
    <div>Good Morning!</div>
} else {
    <div>Greetings</div>
}

This code performs business logic to determine whether it is morning.  A possible refactoring would be to add an IsMorning property to the Model, but in this particular case there is enough similarity between the branches that the entire branching structure could be collapsed by adding a Greeting property to the Model and using it similarly to the following:

<div>@Model.Greeting</div>

Now let’s look at some complex logic around multiple Model properties:

@if (ModelPageNumber + Model.NumbersToDisplay == Model.PageCount
        || (Model.PageCount != Model.CurrentPage
            && !Model.DisplayValues.Contains(Model.PageCount))) {
    <div>There's more to see!</div>
}

In this scenario, not only is the View code difficult to read (you shouldn’t have to play “human compiler” to determine the purpose of the code), but it also complex enough to be at risk for logical errors that cannot be detected without executing the View.  Conditional logic that requires more than a single logical operator should be looked at more closely to determine whether the condition should be evaluated elsewhere and exposed as a single property of the Model.  Moving the logic above outside of the View and exposing a new Model property would simplify the View code to:

@if(Model.HasMoreToSee) {
    <div>There’s more to see!</div>
}

In this posting I have briefly discussed some of the more prominent heuristics that indicate a need to push code from the View into other pieces of the application.  You should now be able to recognize these symptoms when building or maintaining Views (or the Models that support them) in your applications.

Posted On Tuesday, October 9, 2012 8:30 AM | Comments (2) |

Monday, August 27, 2012

Validating a linked item’s data template in Sitecore

I’ve been doing quite a bit of work in Sitecore recently and last week I encountered a situation that it appears many others have hit.  I was working with a field that had been configured originally as a grouped droplink, but now needed to be updated to support additional levels of hierarchy in the folder structure.  If you’ve done any work in Sitecore that statement makes sense, but if not it may seem a bit cryptic.  Sitecore offers a number of different field types and a subset of these field types focus on providing links either to other items on the content tree or to content that is not stored in Sitecore.  In the case of the grouped droplink, the field is configured with a “root” folder and each direct descendant of this folder is considered to be a header for a grouping of other items and displayed in a dropdown.  A picture is worth a thousand words, so consider the following piece of a content tree:

01-content-structure

If I configure a grouped droplink field to use the “Current” folder as its datasource, the control that gets to my content author looks like this:

02-droplink-contents

This presents a nicely organized display and limits the user to selecting only the direct grandchildren of the folder root.  It also presents the limitation that struck as we were thinking through the content architecture and how it would hold up over time – the authors cannot further organize content under the root folder because of the structure required for the dropdown to work.  Over time, not allowing the hierarchy to go any deeper would prevent out authors from being able to organize their content in a way that it would be found when needed, so the grouped droplink data type was not going to fit the bill.

I needed to look for an alternative data type that allowed for selection of a single item and limited my choices to descendants of a specific node on the content tree.  After looking at the options available for links in Sitecore and considering them against each other, one option stood out as nearly perfect – the droptree.  This field type stores its data identically to the droplink and allows for the selection of zero or one items under a specific node in the content tree.  By changing my data template to use droptree instead of grouped droplink, the author is now presented with the following when selecting a linked item:

03-droptree-contents

Sounds great, but a did say almost perfect – there’s still one flaw.  The code intended to display the linked item is expecting the selection to use a specific data template (or more precisely it makes certain assumptions about the fields that will be present), but the droptree does nothing to prevent the author from selecting a folder (since folders are items too) instead of one of the items contained within a folder.  I looked to see if anyone had already solved this problem.  I found many people discussing the problem, but the closest that I found to a solution was the statement “the best thing would probably be to create a custom validator” with no further discussion in regards to what this validator might look like.  I needed to create my own validator to ensure that the user had not selected a folder.  Since so many people had the same issue, I decided to make the validator as reusable as possible and share it here.

The validator that I created inherits from StandardValidator.  In order to make the validator more intuitive to developers that are familiar with the TreeList controls in Sitecore, I chose to implement the following parameters:

  • ExcludeTemplatesForSelection – serves as a “deny list”.  If the data template of the selected item is in this list it will not validate
  • IncludeTemplatesForSelection – this can either be empty to indicate that any template not contained in the exclusion list is acceptable or it can contain the list of acceptable templates

Now that I’ve explained the parameters and the purpose of the validator, I’ll let the code do the rest of the talking:

   1:      /// <summary>
   2:      /// Validates that a link field value meets template requirements
   3:      /// specified using the following parameters:
   4:      /// - ExcludeTemplatesForSelection: If present, the item being
   5:      ///   based on an excluded template will cause validation to fail.
   6:      /// - IncludeTemplatesForSelection: If present, the item not being
   7:      ///   based on an included template will cause validation to fail
   8:      /// 
   9:      /// ExcludeTemplatesForSelection trumps IncludeTemplatesForSelection
  10:      /// if the same value appears in both lists.  Lists are comma seperated
  11:      /// </summary>
  12:      [Serializable]
  13:      public class LinkItemTemplateValidator : StandardValidator
  14:      {
  15:          public LinkItemTemplateValidator()
  16:          {
  17:          }
  18:   
  19:          /// <summary>
  20:          /// Serialization constructor is required by the runtime
  21:          /// </summary>
  22:          /// <param name="info"></param>
  23:          /// <param name="context"></param>
  24:          public LinkItemTemplateValidator(SerializationInfo info, StreamingContext context) : base(info, context) { }
  25:   
  26:          /// <summary>
  27:          /// Returns whether the linked item meets the template
  28:          /// constraints specified in the parameters
  29:          /// </summary>
  30:          /// <returns>
  31:          /// The result of the evaluation.
  32:          /// </returns>
  33:          protected override ValidatorResult Evaluate()
  34:          {
  35:              if (string.IsNullOrWhiteSpace(ControlValidationValue))
  36:              {
  37:                  return ValidatorResult.Valid; // let "required" validation handle
  38:              }
  39:   
  40:              var excludeString = Parameters["ExcludeTemplatesForSelection"];
  41:              var includeString = Parameters["IncludeTemplatesForSelection"];
  42:              if (string.IsNullOrWhiteSpace(excludeString) && string.IsNullOrWhiteSpace(includeString))
  43:              {
  44:                  return ValidatorResult.Valid; // "allow anything" if no params
  45:              }
  46:   
  47:              Guid linkedItemGuid;
  48:              if (!Guid.TryParse(ControlValidationValue, out linkedItemGuid))
  49:              {
  50:                  return ValidatorResult.Valid; // probably put validator on wrong field
  51:              }
  52:   
  53:              var item = GetItem();
  54:              var linkedItem = item.Database.GetItem(new ID(linkedItemGuid));
  55:   
  56:              if (linkedItem == null)
  57:              {
  58:                  return ValidatorResult.Valid; // this validator isn't for broken links
  59:              }
  60:   
  61:              var exclusionList = (excludeString ?? string.Empty).Split(',');
  62:              var inclusionList = (includeString ?? string.Empty).Split(',');
  63:   
  64:              if ((inclusionList.Length == 0 || inclusionList.Contains(linkedItem.TemplateName)) 
  65:                  && !exclusionList.Contains(linkedItem.TemplateName))
  66:              {
  67:                  return ValidatorResult.Valid;
  68:              }
  69:   
  70:              Text = GetText("The field \"{0}\" specifies an item which is based on template \"{1}\". This template is not valid for selection", GetFieldDisplayName(), linkedItem.TemplateName);
  71:   
  72:              return GetFailedResult(ValidatorResult.FatalError);
  73:          }
  74:   
  75:          protected override ValidatorResult GetMaxValidatorResult()
  76:          {
  77:              return ValidatorResult.FatalError;
  78:          }
  79:   
  80:          public override string Name
  81:          {
  82:              get { return @"LinkItemTemplateValidator"; }
  83:          }
  84:      }

 

In this blog entry, I have shared some code that I found useful in solving a problem that seemed fairly common.  Hopefully the next person that is looking for this answer finds it useful as well.

Posted On Monday, August 27, 2012 9:01 AM | Comments (0) |

Tuesday, August 21, 2012

Breaking the silence

Things have been pretty quiet on this blog for the last couple of months because I have been immersed in learning and writing about developing applications for Windows 8 using C# and XAML.  I have been working on authoring “Beginning Windows 8 Application Development – XAML Edition” which will is scheduled for release by Apress in November and is currently available to pre-order on Amazon (http://amzn.com/1430245662).  Still have some work to do on editing, making sure everything survived the RC –> RTM transition, and exorcising the now-taboo “Metro” term, but I hope to have more time for blogging in the coming weeks.

Posted On Tuesday, August 21, 2012 8:25 AM | Comments (0) |

Friday, May 18, 2012

Cross-platform mobile packaging made easy with VSNomad

Since I have been interested in cross-platform mobile application development, but reluctant to leave behind the IDE goodness that is Visual Studio, I was invited to participate in a private early beta program for VSNomad and asked to share my thoughts.  One of the coolest things about the tool is that there is hardly anything to it, so most of this blog entry will be focused around the motivations for a tool like VSNomad rather than "all the things it does".  Access to the early beta program is "by request" as opposed to "invitation only", so I would encourage anyone that has an interest in building cross-platform mobile applications to go to http://www.vsnomad.com, click the Download link, and sign up to be included in the beta.

In the desktop applications world, a reasonable argument can be made for creating native applications that are locked in to a specific OS vendor if accepting that lock-in will put you at a market advantage either by allowing you to create a better product, allowing the product to reach market more quickly, making the product less costly to build and maintain, or some combination of two or more of these factors.  I say there is a reasonable market for this based on the sheer numbers.  Even though Mac has very much increased in popularity and sales, much of that increase has been in the mobile space and many Mac users (even if grudgingly) accept that using VMWare Fusion or Bootcamp to make sure that they have an available instance of Windows available to run "that app" (whatever "that app" which requires Windows is for them).  Various versions of the Windows operating system pretty much dominate the desktop market with the installed base of some Windows version sitting just over 92% of the market, leaving just under 8% for "everyone else" with most of that 8% represented by Mac machines.

The tablet and mobile device story is another thing altogether.  The top players in this market (when lumped together) are the various flavors of Google's Android operating system at right about 50%, with Apple's more unified line coming in at about 30%, leaving still a fairly hefty 20% for "everyone else".  In this world it becomes a much more difficult decision to decide that you're ok with limiting your pool of potential customers to the user of a certain mobile OS, so the drive to either create multiple versions of your app or write your app in such a way that it can be used across platforms is much stronger.

HTML and JavaScript immediately jump to the front when thinking of UI work because these are well-understood and have supporting applications across virtually any modern client computing platforms, but when I think of HTML, I usually think of a browser running "safe" code in a sandboxed environment as opposed to a rich programming platform capable accessing the wide variety of devices and sensors that mark most of today's mobile platforms.  This creates the dilemna - how do we make use of the full capabilities of the device but write our applications in a way that allows us to easily support a variety of mobile platforms? 

The Apache Cordova project answers the question quite nicely by providing an abstraction layer on top of the various devices and services that you can expect to encounter on a mobile platform.  These devices and services include the Accelerometer for motion detection, Camera to capture images and video, Capture for audio, a Compass for directional information, network connectivity state information, a contacts list, basic device data (such as platform and identifying information), File I/O, Geolocation, Media, Notification services (sounds and "toast"), and a client side storage platform for data persistence.  For these services, Cordova becomes the single platform that you code against.  These libraries are packaged together with native shims which are responsible for handling the actual platform-specific interaction and allow the single set of application code to be built for any supported platform.

So now that I've shared the upside of Cordova and you're chomping at the bit to use your mad HTML skills to become a cross-platform mobile ninja, how do you get started?  The answer if you're using Cordova out of the box is "it depends."  The Cordova documentation actually has a seperate Getting Started section for each supporting platform, providing instructions including the installation of Eclipse, each of the supported platform-specific SDKs (for some platforms there will be multiple SDKs), and finally the installation of Cordova itself.  Once all the installation work is done, it's a simple matter of creating a project with the appropriate structure, digging through a few properties files to get them set up for the intended project and target platform, copying jar and js files to the right location in the structure and creating a java bootstrapper to load start page.  Then you can start writing your application.  Doesn't that sound easy and like the developer workflow you'd like to follow?  Me neither!

VSNomad smooths out many of the lumps in the COrdova workflow by providing a Visual Studio addin which is responsible for creating new Cordova projects with the necessary structure and starting files present and once the project is ready to be built for a device, a single button submits the project to VSNomad's cloud-based build service which handles integration with the appropriate SDK for the build target, leaving the developer's main focus on building a useful app.  Using the standard Visual Studio Project Properties paradigm, the user can set an intentionally sparse number of project settings specifying the target platform and supplying any additional information such as developer/app keys for the iOS targets.  Once you've clicked the button to submit your application to the cloud service, the cloud service packages up the application and the extension downloads the package which is now now ready to be deployed on your target device - in my case an apk file to be deployed on my son's Kindle Fire.

By default, the VSNomad project includes the Javascript library for Cordova and jQuery mobile, providing support building rich apps that default to an iOS look and feel.  Import a library like Knockoutjs for its data binding and MVVM support and you've got a very capable stack supported by the productivity inherent to working in Visual Studio.

With Cordova, access to devices and services is made simple so that as a developer you can focus more on WHAT should be done with these capabilities to make apps useful instead of HOW to access them.  VSNomad takes this story a step further by freeing you from mundane setup and configuration tasks and replacing them with a single button click.

Posted On Friday, May 18, 2012 1:00 PM | Comments (2) |

Friday, April 27, 2012

Dependency Injection vs. Service Locator

The Service Locator pattern and Dependency Injection clearly take a much different approach to achieving Inversion of Control and these differences often lead to philosophical discussions about which is better.  Rather than tag either as "better", it is much better to look at the advantages and disadvantages that each bring to the table and understand that at different times and in different scenarios each will assert an edge over the other that makes it the most appropriate choice for that scenario. 

One of the biggest advantages that I see in using Dependency Injection (at least when contructor injection is used as opposed to property injection) is that the component provides a very clear advertisement in the form of constructor arguments as to what external services that it needs in order to complete its job.  This also allows the component to be independent of the mechanism used to provide Inversion of Control because it does not need to be aware of any IoC container or service locator implementation.  If you're not using some sort of framework that is responsible for "building up" components and ensuring dependencies are resolved, the injection approach can also lead to having to invent ways to pass references down through several layers of application code in order to make the reference available to the code that depends upon it, which makes changes at the component level that require the introduction of a new dependency bubble changes through multiple levels.

The biggest advantage that I see in the Service Locator pattern is a direct counter to the advantage of using Dependency Injection.  Because the component does not advertise the dependencies that it has on external services to complete its work the code adheres more closely to the concept of encapsulation.  By advertising external dependencies required to complete work, it can be said that that components using Dependency Injection reveal a bit more of "how" the work is done instead of leaving the entire focus on "what" work is to be completed.  Using the Service Locator approach, there is no need to ensure that service references are passed from layer to layer that may not need them.  This advantage to some degree is countered by the fact that many developers using Inversion of Control will also be using some sort of framework that will handle resolution of dependencies.  Additionally, by removing the explicit advertisement of dependencies on object construction the risk of finding that a necessary service has not been registered late in the process increases and the component cannot "fail early".

All other things being equal, I find that my preferences lean to the explicit model provided with constructor injection and allow whatever IoC container that I am using handle many of the drawbacks of this approach.  This allows me to quickly look at the method signature of the constructor for any class that I have built using this model and understand what it needs to get its job done - a big advantage when trying to quickly understand problems with production code.  There are some times when you find that your component MUST support a public constructor with no arguments and others when it is not required but does make sense to do so.  In these cases, the Service Locator becomes a valuable tool to make services available to your component.

Posted On Friday, April 27, 2012 8:31 AM | Comments (1) |

Wednesday, April 18, 2012

"The Cloud" brings radical changes to our programming approach

Have you heard about this new Cloud stuff?  It's a new programming model that is introduced with Microsoft Windows Azure, Amazon's EC2, and other large data center providers and it's going to radically change the way that we approach programming.  Among some of the key changes to recommended programming practices are:

  • Make sure to use coarse grained interfaces.  When calling across logical tiers, assume that you will at best be crossing processes and very likely be crossing machine boundaries, so make as few calls as practical to get the job done.
  • Design long running processes so that markers or some similar mechanism can give you the necessary information to resume processing instead of double-processing.
  • Use of queue-based processing will allow for either scaling out by adding more processors or, when possible, allow load to be leveled over time with fewer processors.  This will also allow components or subsystems to function while others are not running or are running at diminished capacity.
  • State in our services should be avoided if at all possible

Come to think about it, maybe this is that new Microsoft Transaction Server thing I've been hearing about.

The fundamentals of good programming don't change when we move to the cloud - they're just repackaged and brought back into the spotlight.  You may not be ready now or even ever to take your apps to the cloud, but what's wrong with programming now like you're already there?

Posted On Wednesday, April 18, 2012 12:06 PM | Comments (1) |

Thursday, March 22, 2012

Stop trying to be perfect

Yes, Bob is my uncle too.  I also think the points in the Manifesto for Software Craftsmanship (manifesto.softwarecraftsmanship.org) are all great.  What amazes me is that tend to confuse the term “well crafted” with “perfect”.  I'm about to say something that will make Quality Assurance managers and many development types as well until you think about it as a craftsman – “Stop trying to be perfect”.

Now let me explain what I mean.  Building software, as with building almost anything, often involves a series of trade-offs where either one undesired characteristic is accepted as necessary to achieve another desired one (or maybe stave off one that is even less desirable) or a desirable characteristic is sacrificed for the same reasons.  This implies that perfection itself is unattainable.  What is attainable is “sufficient” and I think that this really goes to the heart both of what people are trying to do with Agile and with the craftsmanship movement.  Simply put, sufficient software drives the greatest business value.

 

I've been in many meetings where “how can we keep anything from ever going wrong” has become the thing that holds us in analysis paralysis.  I've also been the guy trying way too hard to perfect some function to make sure that every edge case is accounted for.  Somewhere in there, something a drill instructor said while I was in boot camp occurred to me.  In response to being asked a question by another recruit having to do with some edge case (I can barely remember the context), he said “What if grasshoppers had machine guns?  Would the birds still **** with them?”  It sounds funny, but there's a lot of wisdom in those words.

 

“Sufficient” is different for every situation and it’s important to understand what sufficient means in the context of the work you’re doing.  If I’m writing a timesheet application (and please shoot me if I am), I’m going to have a much higher tolerance for imperfection than if you’re writing software to control life support systems on spacecraft.  I’m also likely to have less need for high volume performance than if you’re writing software to control stock trading transactions.

 

I’d encourage anyone who has read this far to instead of trying to be perfect, try to create software that is sufficient in every way.  If you’re working to make a component that is sufficient “better”, ask yourself if there is any component left that is not yet sufficient.  If the answer is “yes” you’re working on the wrong thing and need to adjust.  If the answer is “no”, why aren’t you shipping and delivering business value?

Posted On Thursday, March 22, 2012 7:10 AM | Comments (1) |

Powered by: