Friday, October 29, 2010

Windows 7 Phone - Proof that Microsoft has to hire cooler people

This week I'm moving from CRM Land and visiting the nearby island of Windows 7 Phone (or abbreviated WP7).  If you've been following the PDC online (http://player.microsoftpdc.com/) then you know that Microsoft has reentered the mobile market with a take no prisoners attitude.  The tools are free; including a commercial grade version of Dotfuscator and Preemptive’s analytics tool (announced at the PDC), the hardware is top notch, and the applications look great (Bejeweled, Facebook, Intuit’s TaxCaster, Amazon Kindle).  Overall it is a great platform and product that should be a game changer for Microsoft.  This is why I can’t help but ask; when did Microsoft start hiring geeks in their marketing department?
First there is the name.  Currently in the market there are two real competitors; Apple with the iPhone, and Google with the Android.  The iPhone carries the name recognition established with the iPod, and the Android; with its abbreviated version Droid, is just a cool name.  So why did Microsoft go with Windows 7 Phone?  As a geek, I get it, you can run the same Silverlight applications that run on your Windows 7 desktop right on your phone (see Viewing 3-Screen Coding: Sharing code between Windows ... http://bit.ly/aUlqkU ), but only us geeks are going to get that.  Furthermore it just doesn’t stick in your mind the way iPhone or Android does.
Next there are the commercials.  Someone really dropped the ball here.  The commercials show just how much people love and get captivated by their competitor’s smart phones.  While as a geek, I love the fact that I can look at the start screen of the WP7 and know how many emails I have and who they are from or who the call I missed is from, my daughter and girlfriend just love fiddling with their phones.  My prediction; Apple or Google will air the exact same commercial, but at the end someone will look at the camera and say “Yeah, I love my phone that much!”  It’s only us geeks who see our phone as a tool, to the rest of the target audience it is a toy that they just can’t get enough of.
Speaking of the start screen for the WP7, I think Microsoft went a little too far to differentiate themselves from their competition here.  As I was watching the PDC presentation, my daughter walked in from another room and saw the WP7 start screen for the first time.  She had seen the Games hub and some of the applications before, but this was the first time she had seen the start screen.  She asked if I was working on a children’s game.  When I explained that this was the start screen for the phone I was planning to get, she laughed, left the room and returned with blocks from her two year old cousin’s toy box.  She stacked them in an arrangement that looked remarkably like the phone on the screen.  I love the dynamic tiles, and I think they are a great feature of the phone.  It might have been nice if they had followed the pattern of the Android’s widgets and allowed both tiles and icons on the start screen though.  While as a geek I can appreciate the tiles for their extensibility and the quick view information they provide, the rest of the world isn’t likely to get it.  More importantly (from my geek point of view), I’m also a little worried about the battery life of the phone.  The OLED (organic light emitting diode) technology behind the screens of smart phones uses less power the more black it displays on the screen.  This is one of the reasons why many smart phone applications use a dark color scheme.  Icons have much more black space than the tiles used by WP7 and therefore are easier on the battery.  I’m hoping that Microsoft at least considered this and didn’t sacrifice battery life for product differentiation.
My advices to Microsoft, hire a better marketing team with less of a geek factor, and don’t let Steve Ballmer talk to long on stage when introducing a product (we love him, but he’s no salesman).  The WP7 platform is phenomenal, and there is a lot of potential here, but to take advantage of it they will need to appeal to a very different audience than the original Windows mobile devices were targeting.    The days when only geeks own smart phones are over, and its time to start selling to those who want the smart phone for the superficial look at my new toy reasons, not just for the practical things it can do.

Thursday, September 16, 2010

ICrmService vs CrmService

If you have written a plugin for Dynamics CRM, you have probably had to create an instance of the CrmService class.  The template for writing plugins for CRM includes the following code:


 // Create a Microsoft Dynamics CRM Web service proxy.
 // TODO Uncomment or comment out the appropriate statement.

 // For a plug-in running in the child pipeline, use this statement.
 //CrmService crmService = CreateCrmService(context, true);

 // For a plug-in running in the parent pipeline, use this statement.
 ICrmService crmService = context.CreateCrmService(true);

The first thing that should strike the developer as odd is that for the child pipeline a CrmService is used and for the parent pipeline a ICrmService interface is used.  I made the unfortunate assumption that CrmService could be cast to ICrmService and used a single ICrmService instance in my code instead, since naturally CrmService must implement ICrmService right?

Of course making such assumptions always get you into trouble.  Perhaps the Microsoft CRM team was asleep when covering object oriented design or perhaps they never read Head First Design Patterns by Freeman & Freeman (possibly one of the best books on software engineering ever written).  We will never know why ICrmService wasn't implemented in their CrmService class, but a runtime error is generated when trying to make the cast. 

Even though Microsoft chose to ignore the principles of good object oriented design, that isn't an excuse for us to ignore them.  Oddly, the CrmService implements every method from ICrmService with the same signature with the exception of one method, Execute.  Fortunately design patterns gives us an answer (is there anything design patterns can't do?) through the adapter pattern.  Its fairly straightforward to create a wrapper for CrmService that will expose it through an ICrmService interface.  The following code demonstrates:


/// <summary>
/// Implement wrapper for CrmService to expose it through a ICrmService interface
/// </summary>
public class CrmServiceWrapper:ICrmService
{
    private CrmService _service;

    public CrmServiceWrapper(CrmService service)
    {
        _service = service;
    }

    public Guid Create(BusinessEntity entity)
    {
        if (_service!=null)
        {
            return _service.Create(entity);
        }
        return Guid.Empty;
    }

    public void Delete(string entityName, Guid id)
    {
        if (_service != null)
        {
            _service.Delete(entityName,id);
        }           
    }

    /// <summary>
    /// Execute, this is the only method that is different from the interface,
    /// so we should check the parameter to insure that the passed object
    /// is actually a Request
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public object Execute(object request)
    {
        if (_service != null)
        {
            if (!(request is Request))
            {
                throw new ArgumentException("Object passed must be a Request object.", "request");
            }
            return _service.Execute((Request)request);
        }
        return null;
    }

    public string Fetch(string fetchXml)
    {
        if (_service != null)
        {
            return _service.Fetch(fetchXml);
        }
        return null;
    }

    public BusinessEntity Retrieve(string entityName, Guid id, Microsoft.Crm.Sdk.Query.ColumnSetBase columnSet)
    {
        if (_service != null)
        {
            return _service.Retrieve(entityName, id, columnSet);
        }
        return null;
    }

    public BusinessEntityCollection RetrieveMultiple(Microsoft.Crm.Sdk.Query.QueryBase query)
    {
        if (_service != null)
        {
            return _service.RetrieveMultiple(query);
        }
        return null;
    }

    public void Update(BusinessEntity entity)
    {
        if (_service != null)
        {
            _service.Update(entity);
        }
    }

    public void Dispose()
    {
        if (_service != null)
        {
            _service.Dispose();
        }
    }
}

By using this class any code written for your plugins can safely be written against the ICrmService interface (as it should be) without you having to worry about whether your code is being called from the parent or child pipeline.  Hopefully Microsoft will include this in a future version so that the wrapper isn't necessary.