# Monday, November 28, 2011

Lately it seems that I’m been doing a lot of posts referring to “a customer”.  Often they are different customers, but it really sounds impersonal, so in this one I’m going to name names and point fingers – in a friendly way, of course.

Last week Nicolas emailed me to get some advice on the Visual Studio 2008 Forms designer and the Compact Framework.  Specifically he wanted to know if it’s possible to get a custom TabControl to be designable.  My assumption is that either he’s inheriting from the stock version or they’ve created a fully custom control inheriting from ContainerControl – I didn’t ask because in either case the answer is simple: it’s not going to work in the designer.

I told him that it won’t work, but in retrospect I feel I’ve short-changed him a bit.  As a developer, I like to hear a bit more than an “abandon all hope, ye who sail here for there be sea monsters” kind of response.  Why doesn’t it work?  More importantly, what are my options for a workaround?

In this case it’s interesting to note that even if he could get the designer to work for this control, I’d recommend that he not do it.  And they why to that recommendation is far more interesting.

So, Nicolas, here’s the longer answer to your question.

First, you have to understand that the Studio Designer is very, very brittle.  Any little quirkiness tends to send it into fits, and once broke you often spend large amounts of time unloading things, resetting the toolbox, restarting Studio or even restarting the PC.  This is a huge time drain, so avoiding situations that break the designer is the first order of business.

Getting the designer working for a CF component is even worse.  CF controls often make use of things that the desktop doesn’t even have, which the designer really hates.  You also have to build the Controls for both versions of the CF (for Nicolas this is important since, at least last time I was with his team, they had versions of the application targeting CF 2.0 and CF 3.5).  A control built against CF 3.5 will never show up in the designer of a CF 2.0 project.  There’s also a major bug in the designer that limits CF 3.5 controls that I’ve written about before.

For designer support you also have to maintain an XMTA file and often end up having condition compiler statements which really make the code less readable.  Workarounds for most of these issues exist.  You can create separate set of “designer” assemblies that provide only stuff for the designer and minimal actual control logic.  The problem with this is that you then have to maintain these things, which sucks up developer time that should be spent actually solving your business problem.

You can’t create a desktop assembly and use it for the designer because the designer will then suck in the full .NET framework as a reference and attempt to deploy that to the device when you want to debug.

So if the designer is so brittle and worthless, what’s a developer to do?  Well, my general attitude is to provide “support” only for basic Controls, and by “support” I mean the inherent capability of the designer to show a box with the location and bounds of your control.  No rendering.  No styling.  No collection editing. 

Really the designer’s primary use for me is to aid in basic layout.  I need to put a Control on a Form, set it’s location and Size and that’s it anyway.  Anything else is done via code, and there’s nothing wrong with this.  Embrace it as how you must work and your life becomes much simpler.

That’s all well and good for a simple Control, but what about a container like Nicolas is after?  His team would like to be able to drop on a Tab control and design each individual Tab, right?  So what are they to do?

Well, I think they’re looking at the problem wrong to begin with.  I don’t blame them, people have been looking at this wrong for some time, and the simple existence of the TabControl tend to push people to look at it wrong.  In general, my recommendation is to not use the TabControl in the first place. 

First of all, it’s 2011.  That ass-looking TabControl would have been ok back in 1995 (if the devices had existed then) since it looks just like the ass-looking Windows 95 interface. 

It’s was an ok solution in 2000 when these devices were new and people thought of them as just “mini PCs” so extending the desktop paradigm to the device was what we did.    Yes, we wished we could do a little more to make it pretty by adding icons and custom drawing, but it worked and users really didn’t expect anything more.

But it’s 2011.  Users don’t use a stylus if they can avoid it.  They know an elegant UI when they see one because they’ve been using a smartphone.  Just because they have no choice in the app they use (this is an LOB app, so the user is locked in) is no excuse to not deliver something that is actually nice to use.  The TabControl does not meet that.  It’s tiny, it scrolls weird, and it’s ugly with no options to make it non-ugly.  Plus it’s  Tab motif.  Name the last mobile app you used on a phone that used tabs.  That’s what I thought. Abandon the piece of crap.

So what would I use?  Obviously this will be subjective, as it’s what I would personally do given a blank slate.  Nicolas is trying to put something into an already-existing, very large code base, so his mileage may vary, but I’m betting it won’t be too bad, and implementing this might actually do a lot toward getting other gains they really need like better transition time between views.

I’d start using the OpenNETCF IoC project.  I’d split each of the existing “tabs” into individual SmartParts, which are now fully designable since they’re just UserControls.  So there you are – the designer requirement is solved.  I’d then place on the Form a pair of DeckWorkspaces.  One would display the “selected” view and the other would replace the “tabs” of old with buttons or clickable images that would be used to select the current view.  It would look something like this in the designer for the Form:

tabs

And then the SmartPart that goes into the bottom workspace might be something like this in the designer (well it would probably be a bit different, but you get the idea):

tabs2

See, the designer works.  It meets the business requirement that it provides a “tab-like” capability where the user selects an item across the bottom and the upper view changes.  But now it’s not just usable with a stylus but it’s also likely to be usable with a finger (gasp!) and aesthetically it doesn’t make my want to poke my own eyes out.  It’s a win-win.  Plus now you can lazy-load the views *on demand* rather than loading up every damned control on every tab when the Form is brought up, so the user is going to be pleasantly surprised there too.  Oh, and now it’s easy to change out “tabs” based on user rights or workflow and probably other benefits that I’m not thinking of.

Occasionally we’ve got to break out of the “what we know” and the “what we’ve always done” routine and look out at the horizon.  By doing so we can often make some simple changes and make things easier for both the developer and the user, and that is how we make progress.

Monday, November 28, 2011 12:24:00 PM (Central Standard Time, UTC-06:00)  #     | 
# Wednesday, November 23, 2011

I've published new updates to our MTConnect projects on Codeplex. Both the MTConnect SDK and the VirtualAgent have changes and for detailed info take a look at the change logs in the Source tabs on the project.  Here's a high-level list of what I think the important additions are:

  • I've added a fully working reference implementation of an MTConnect Adapter for Okuma THINC controllers (full source is included).  If you have an Okuma machine with a THINC-supported controller on it, you now have a simple agent and adapter you can drop onto the machine to start publishing data immediately. I hope to find time to put together a reference implementation for Fanuc FOCAS controllers.  If you're interested or in need of that support, let me know and we can discuss prioritizing it and the features you need.
  • I've added support for SHDR adapters.  At the [MC]2 conference in Cincinnati there was concern that once you selected an Agent technology (either ours or the reference MTConnect C++ Agent), then you were locked in to creating Adapters only for that Agent.  That is no longer the case.  Our Virtual Agent now can easily consume data from your existing C/C++ Adapters written against the reference Agent.  No changes are required in your existing Adapters at all.

If you have any questions on implementation, etc, feel free to contact me.  For more info on our entire line of MTConnect products, take a look at our web site.

Wednesday, November 23, 2011 11:46:09 AM (Central Standard Time, UTC-06:00)  #     | 
# Tuesday, November 22, 2011

So a customer asked me last week if I could provide them some managed code to allow them to insert a certificate and a private key into the certificate store on a Windows CE device.  A simple enough request, right?  Heh, isn’t that how they all start?

To be honest, I’ve done very little work with certificates in the past – basically I’ve created certs for use with Padarn and SSL but that’s about it. So my first order of business was to do some due diligence to try to get an idea of the scope of the problem.  I pulled up the MSDN docs of the Compact Framework’s support for X509 stuff.  It shows that there is device support for the X509Store as well as the X509Certificate so I told them it should be pretty easy to achieve their goal.  I mean the docs sure look like it would be easy.

Next I needed to write a little code to familiarize myself with the object model.  I fired up a device that most definitely has several certificates installed.

CECerts

Then I wrote some simple code to give me an idea which of the six stores these fall into:

public void DumpCertCounts() 
{ 
    Debug.WriteLine("        Current User     Local Machine");

    var userStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser); 
    var deviceStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("Root:          {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
    
    userStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("My:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count));

    userStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("CA:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
} 

Easy enough.  The problem was that then I actually ran the code.  This is the output.

CECertDbg

Really?  Zero certificates in any store?  Was my code right?  Yes.  Did I target the right device from the debugger?  Yes.  Alrighty, so it seems that “existence of a class in the BCL” doesn’t necessarily mean “actual functionality is implemented.”  This doesn’t bode well.

Technically I don’t need to know what certificates are installed on the device for the customer’s request, right.  Sure, it would be nice to see if a cert is there before trying to install it, but we can always just wrap the call in a try/catch and ignore any exception thrown when we try to install a duplicate.  Not the ideal solution, but workable since this will be done infrequently.

I then generated some test certs with makecert.exe and pushed them to the device.  Now I needed to create code to import them, hopefully an import works better than enumerating existing certs. 

Let’s see, how would we bring in a cert?  How about the Import method on the X509CerticateCollection?  Oh, not supported in the CF.

Ah, but the Add method is, so I just need to create an X509Certificate and Add it.  Let’s see, the X509Certifiacte class has two static methods – CreateFromCertFile and CreateFromSignedFile.  Of course those aren’t supported in the CF.  That would be too easy.

How about from a constructor? Looks like the only constructor supported is the one that takes in a byte array.  What on earth is that byte array.  Oh, the example shows that it’s easy to get by Exporting from a certificate you already have.  How un-useful is that?

So it appears that the entire namespace in the Compact Framework is useless.  Actually worse than useless because I can’t create a direct replacement or I’ll end up with naming conflicts with the existing useless garbage.

So now I have to create the objects in the namespace and implement the methods required to achieve “import a certificate into the device store”.  The starting point is the C source code for the Certificates control panel applet you see above, which ships with Platform Builder.  It’s an ugly load of P/Invoking methods that deal with lots of pointers to structs that contains pointers to structs that contain pointers to structs that contain…you get the idea.

So I spent a day just getting the import of a CER file working (much easier than the PVK import is going to be) and my exact same test code now outputs this:

CECertDbg2

See, an implementation that actually does something.  I have no idea what was going on at Microsoft when this namespace was “implemented” or how it got out the door.  It definitely wouldn’t pass even the most rudimentary of functional tests.

This is a classic case of why I’d love to see the Compact Framework open/shared sourced.  I could actually go in and fix these things.

Tuesday, November 22, 2011 10:41:17 AM (Central Standard Time, UTC-06:00)  #     | 
# Monday, November 21, 2011

This post is part of my "Software Development" series. The TOC for the entire series can be found here.


Let’s start this post with a couple questions.  What is an ORM and why would you use one?  If you don’t know the answer to both of these questions, then this post is for you.  If you do know the answers, feel free to skip to the next post (after I’ve created it of course).

First, let’s look at what an ORM is. And ORM is an object-relational mapping.  According to Wikipedia, which we all know is the infallible and definitive resource for all knowledge, and ORM is “a programming technique for converting data between incompatible type systems in object-oriented programming languages.”  Ok, what the hell does that mean?  My definition is a little less “scholarly.”  I’d say that

An ORM is a way to abstract your data storage into simple class objects (POCOs if you’d like) so that you don’t have to worry about all the crap involved in actually writing data fields, rows, tables and the like.  As a developer, I want to deal with a “Person” class.  I don’t want to think about SQL statements.  I don’t want to have to worry about indexes or tables or even how my “Person” gets stored to or read from disk.  I just want to say “Save this Person instance” and have it done.  THAT is what an ORM is.  A framework that lets me concentrate on solving my business problem instead of spending days writing bullshit, mind-numbing, error-prone data access layer code.

Why would we use an ORM?  I think I’ve been fairly upfront that I consider myself to be a lazy developer.  No, I don’t mean that I take shortcuts or do shoddy work, I mean that I hate doing things more than once.  I hate having to write reams of code to solve problems that have already been solved.  I’ve been writing applications that consume data for years, and as a consequence, I’ve been writing data access code for years.  If you’re not using an ORM, you probably know down in your soul that this type of work flat-out sucks.  Anything that simplifies data access to me is a win.

Of course there are other, more tangible benefits as well.  If you’re using an ORM, it’s often possible to swap out data stores – so maybe you could write to SQL Server then swap a line of two in configuration and write to MySQL or an XML file.  It also allows you to mock things or create stubs to remove data access (really handy when someone tells you that your data access is what’s slowing things down when you’re pretty sure it’s not).

I can see that some of you still need convincing.  That’s good – you shouldn’t ever just take someone’s word for it that they know what they’re doing.  Ask for proof.  Well let’s look at a case of my own code, why I built the OpenNETCF ORM and how I was recently reminded why it’s a good thing.

A couple years ago I wrote an application for a time and attendance device (i.e. a time clock) that, not surprisingly, stored data about employees, punches, schedules, etc.  on the device.  It also has the option to store it on a server and synchronize the data from clock to server, but that’s not core to our discussion today.  The point is that we were storing a fair bit of data and this was a project I did right before I create the ORM framework.  It was, in fact, the project that made it clear to me that I needed to write an ORM.

Just about a month ago the customer wanted to extend the application, adding a couple features to the time clock that required updates to how the data was stored.  It took me very little time to realize that the existing DAL code was crap.  Crap that I architected and wrote.  Sure, it works.  They’ve shipped thousands of these devices and I’ve heard no complaints and had no bug reports, so functionally it’s fine and it does exactly what was required.  Nonetheless the code is crap and here’s why.

First, let’s look at a table class in the DAL, like an Employee (the fat that the DAL knows about tables is the first indication there’s a problem):

internal class EmployeeTable : Table 
{ 
    public override string Name { get { return "Employees"; } }

    public override ColumnInfo KeyField 
    { 
        get  
        { 
            return new ColumnInfo { Name = "EmployeeID", DataType = SqlDbType.Int }; 
        } 
    }

    internal protected override ColumnInfo[] GetColumnInfo() 
    { 
        return new ColumnInfo[] 
        { 
            KeyField, 
            new ColumnInfo { Name = "BadgeNumber", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "BasePay", DataType = SqlDbType.Money }, 
            new ColumnInfo { Name = "DateOfHire", DataType = SqlDbType.DateTime }, 
            new ColumnInfo { Name = "FirstName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "LastName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            // ... lots more column definitions ... 
        }; 
    }

    public override Index[] GetIndexDefinitions() 
    { 
        return new Index[] 
        { 
            new Index 
            { 
                Name = "IDX_EMPLOYEES_EMPLOYEEID_GUID",  
                SQL = "CREATE INDEX IDX_EMPLOYEES_EMPLOYEEID_GUID ON Employees (EmployeeID, GUID DESC)" 
            }, 
        }; 
    } 
}

So every table for an entity derives from Table, which looks like this (shorted a load for brevity in this post):

public abstract class Table : ITable 
{ 
    internal protected abstract ColumnInfo[] GetColumnInfo();

    public abstract string Name { get; } 
    public abstract ColumnInfo KeyField { get; }

    public virtual string GetCreateTableSql() 
    { 
        // default implementation - override for different versions 
        StringBuilder sb = new StringBuilder(); 
        sb.Append(string.Format("CREATE TABLE {0} (", Name));

        ColumnInfo[] infoset = GetColumnInfo(); 
        int i; 
        for (i = 0; i < (infoset.Length - 1); i++) 
        { 
            sb.Append(string.Format("{0},", infoset[i].ToColumnDeclaration())); 
        }

        sb.Append(string.Format("{0}", infoset[i].ToColumnDeclaration())); 
        sb.Append(")");

        return sb.ToString(); 
    }

    public virtual Index[] GetIndexDefinitions() 
    { 
        return null; 
    }

    public virtual IDbCommand GetInsertCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command

        return cmd; 
    }

    public IDbCommand GetUpdateCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }

    public IDbCommand GetDeleteCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }


Sure, I get a few bonus points for using inheritance so that each table doesn’t have to do all of this work, but it’s still a pain.  Adding a new Table required that I understand all of this goo, create the ColumnInfo right, know what the index stuff is, etc.  And what happens when I need to add a field to an existing table?  It’s not so clear.

Now how about consuming this from the app?  When the app needs to get an Employee  you have code like this:

public IEmployee[] GetAllEmployees(IDbConnection connection) 
{ 
    List list = new List();

    using (SqlCeCommand command = new SqlCeCommand()) 
    { 
        command.CommandText = EMPLOYEES_SELECT_SQL2; 
        command.Connection = connection as SqlCeConnection;

        using (var rs = command.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Insensitive)) 
        { 
            GetEmployeeFieldOrdinals(rs, false);

            while (rs.Read()) 
            { 
                IEmployee employee = EntityService.CreateEmployee();

                employee.BadgeNumber = rs.IsDBNull(m_employeeFieldOrdinals["BadgeNumber"]) 
                    ? null : rs.GetString(m_employeeFieldOrdinals["BadgeNumber"]); 
                employee.BasePay = rs.IsDBNull(m_employeeFieldOrdinals["EmployeeNumber"]) 
                    ? 0 : rs.GetDecimal(m_employeeFieldOrdinals["BasePay"]); 
                employee.DateOfHire = rs.IsDBNull(m_employeeFieldOrdinals["DateOfHire"]) 
                    ? DateTime.MinValue : rs.GetDateTime(m_employeeFieldOrdinals["DateOfHire"]); 
                employee.EmployeeID = rs.GetInt32(m_employeeFieldOrdinals["EmployeeID"]); 
                employee.FirstName = rs.GetString(m_employeeFieldOrdinals["FirstName"]); 
                employee.LastName = rs.GetString(m_employeeFieldOrdinals["LastName"]); 
                string middleInitialStr = !rs.IsDBNull(m_employeeFieldOrdinals["MiddleInitial"]) 
                    ? rs.GetString(m_employeeFieldOrdinals["MiddleInitial"]) : String.Empty; 
                employee.MiddleInitial = String.IsNullOrEmpty(middleInitialStr) ? '\0' : middleInitialStr[0]; 

                 // on and on for another 100 lines of code) 

                 list.Add(employee); 
            } 
        } 
    }

    return list.ToArray(); 
} 

Nevermind the fact that this could be improved a little with GetFields – the big issues here are that you have to hard-code the SQL to get the data, then you have to parse the results and fill out the Employee entity instance.  You do this for every table.  You change a table, you then have to go change the SQL and every method that touches the table.  The process is error prone, time consuming and just not fun.  It also makes me uneasy because the test surface area needs to be big.  How do I ensure that all places that access the table were fixed?  Unit tests help give me some comfort, but really it has to go through full integration testing of all features (since Employees are used by just about every feature on the clock).

Now what would the ORM do for me here?  Without going into too much detail on exactly how to use the ORM (we’ll look at that in another blog entry), let’s just look at what the ORM version of things would look like.

We’d not have any “Table” crap.  No SQL.  No building Commands and no parsing Resultsets.  We’d just define an Entity like this:

[Entity] 
internal class Employee 
{ 
    [Field(IsPrimaryKey = true)] 
    public int EmployeeID { get; set; }        
    [Field] 
    public DateTime DateOfHire { get; set; } 
    [Field] 
    public string FirstName { get; set; } 
    [Field] 
    public string LastName { get; set; }

    // etc. 
}

Note how much cleaner this is than the Table code I had previously.  Also note that this one class replaces *both* the Table class and the Business Object class.  So this is much shorter.

What about all of that create table, insert, update and delete SQL and index garbage I had to know about, write and maintain?  Well, it’s replaced with this:

m_store = new DataStore(databasePath);

if (!m_store.StoreExists) 
{ 
    m_store.CreateStore(); 
}

m_store.AddType<Employee>(); 

That’s it.  Adding another Entity simply requires adding just one more line of code – a call to AddType for the new Entity type.  In fact the ORM can auto-detect all Entity types in an assembly with a single call if you want.  So that’s another big win.  The base class garbage gets shifted into a framework that’s already tested.  Less code for me to write means more time to solve my real problems and less chance for me to add bugs.

What about the long, ugly, unmaintainable query though?  Well that’s where the ORM really, really pays off.  Getting all Employees becomes stupid simple.

var allEmployees = m_store.Select<Employee>();  

Yep, that’s it. There are overloads that let you do filtering.  There are other methods that allow you to do paging.  Creates, updates and deletes are similarly easy. 

Why did I create my own instead of using one that already exists?  Simple – there isn’t one for the Compact Framework.  I also find that, like many existing IoC frameworks, they try to be everything to everyone and end up overly complex.  Another benefit to the OpenNETCF ORM is that it is fully supported on both the Compact and Full Frameworks, so I can use it in desktop and device projects and not have to cloud my brain with knowing multiple frameworks.  I even have a partial port to Windows Phone (it just needs a little time to work around my use of TableDirect in the SQL Compact implementation). 

Oh, and it’s fast.  Really fast.  Since my initial target was a device with limited resources, I wrote the code for that environment.  The SQL Compact implementation avoids using the query parser whenever possible because experience has taught me that as soon as you write actual SQL, you’re going to pay an order of magnitude performance penalty (yes, it really is that bad).  It uses TableDirect whenever possible.  It caches type info so reflection use is kept to a bare minimum.  It caches common commands so if SQL was necessary, it at least can reuse query plans.

So that’s why I use an ORM. Doing data access in any other way has become insanity.

Monday, November 21, 2011 11:08:06 AM (Central Standard Time, UTC-06:00)  #     | 
# Wednesday, November 16, 2011

REST web services are pretty straightforward and really, really common (you used one to read this blog page).  As software gets implemented as services, it's getting more and more common for us as developers to have to make REST calls programmatically.  Lately I've been implementing a lot of services using Padarn on both the device and the PC and then implementing client libraries to access those services.  In doing so, it only made sense to create some infrastructure to make my life a little easier, and so the RestConnector (and DigestRestConnector) was born.

For a simple GET, such as to get the response for this page, the code is trivial:

 

var connector = new RestConnector("blog.opennetcf.com");
var response = connector.Get("/ctacke");

Other verbs like POST and PUT are nearly as simple.

var response = connector.Post("/upload", myData);

For services that require authentication, there's the DigestRestConnector that behaves the same, except the ctor takes in a UID/PWD pair as well. The classes support the four common verbs I use: GET, PUT, POST and DELETE. Of course since it's open-source, feel free to extend them as you wish.


The OpenNETCF Extensions library is a collection of extension methods and helper classes that I find useful in a lot of different projects. It's compatible with the Compact Framework, Tirethe full framework and Windows Phone.

Wednesday, November 16, 2011 9:27:40 AM (Central Standard Time, UTC-06:00)  #     |