Sunday, November 23, 2014

ORM comparison: NHibernate loses to Entity Framework

I think that NHibernate is better than Entity Framework in several ways. Especially when it comes to NHibernate's ability to change the Code First model so easily without dropping and recreating the database. No data migrations, if you add a column to your model, a column is added to your database.

So it's easier in many ways, different in others, a little harder in others, but today I found a situation I was surprised that NHiberate simply loses to Entity Framework. The support to convert String.Contains to a Like expression is never a problem in Entity Framework in which you can use String.Contains on an entity in a LINQ expression built using a query or extension methods.

In NHibernate, using the String.Contains method results in an exception that says: "Unrecognised method call: System.String:Boolean Contains(System.String)"

To my surprise I had to create NHibernate.Criterion.ICriterion expressions similar to LINQ expressions.

var search = session.QueryOver<PersonHBN>()
                        .Where(new NHibernate.Criterion.AndExpression(
                            new NHibernate.Criterion.EqPropertyExpression("OtherEntity.id"NHibernate.Criterion.Projections.Constant(id)), 
                            new NHibernate.Criterion.LikeExpression("name"text)));

That was so much for just x.name.Contains(text)! But it is good to see that in NHibernate, there is an expression system that is similar to that of LINQ expression which is very powerful.

Saturday, November 1, 2014

I promise I'll let you know where I am (HTML5 GeoPosition API)

One of my friends is such a sweetheart. Whenever I drop her home she's concerned about me especially because she knows how I drive so she asks me to promise her that I'll let her know when I reach my home. Sometimes I do, sometimes I forget, and sometimes she calls me to ask.

She came to my mind while I was playing today with jQuery's deferred and JavaScript 6 promises with the GeoLocation API, i.e. navigator.geolocation.getCurrentPosition(successcalback, failcallback, options);

Promises is a standard part of EcmaScript 6 and is natively supported in modern browsers. It is an alternate way to handling asynchronocity prevalent in modern web applications and much cleaner than callbacks in certain situations. Callbacks are better suited in other asynchronous situations (for example a UI event).

Just to try promises out (native and jQuery's deferred), I'll ask the user for their location as a promise. I might get the location, a declination, or I will wait forever (until the browser's page is closed).

The only native geolocation API relies on callbacks as you can see from the signature above with the success and failure callback parameters. To use promises, I'm going to use a jQuery deferred object (an object that is eventually resolved), and abstract the geolocation API with a function that returns a promise of the geolocation (or a declination, and otherwise we'll just wait forever). The function locationPromise below does so.

If you often ask the user for their location using getCurrentPosition, you might want to use a promise-styled API just like the one below.

function locationPromise() {
    var def = $.Deferred();
    var gotLocation = function (geopos) {
        def.resolveWith(geopos);
    }
 
    var notLocation = function () {
        def.rejectWith("Wonder where you are!");
    }
    window.navigator.geolocation.getCurrentPosition(gotLocation, notLocation, {});
 
    var myPromise = def.promise();
    return myPromise;
}

We use this function as follows:

function getLocationPromise() {
    locationPromise()
        .done(function () {
            //this will be the value resolved or rejected
            console.log(this.coords);
        })
        .fail(function () { alert("sorry weren't able to get pos"); });
}

The usefulness of this depends on the architecture of your application. You base your architecture on common functionality that handles promises with metadata (for example as how to respond to success or failure) instead of callbacks. So this examples shows how you can convert an asynchronous HTML5 operation (geolocation) to a promise.

Sunday, September 21, 2014

Reflection: A PDF document must be opened with PdfDocumentOpenMode.Import to import pages from it.

The solution for the problem is very obvious as outlined below, so this is a reflection on developer behavior and API friendliness.

This is not a logical bug: a lot of times programmers are not faced with algorithmic challenges. In the code snippet below, there is nothing much to this for loop that add pages from a PdfDocument to another using PDFSharp.

foreach(var reportStream in reportStreams)
{
    var pdfDoc = PdfReader.Open(reportStream);
    foreach (PdfPage page in pdfDoc.Pages)
    {
        majorDoc.Pages.Add(page);
    }
}

Developers do not scratch their heads to write that piece of code, but sometimes the simplest things take time and effort because developers do not understand how APIs work. We live in a software development world that is filled with APIs whether on the web or local and for most using APIs is a natural part of their jobs which is good until the benefits of using the API e.g. avoid reinventing the wheel and making use of others who studied the object of the API more in depth, are outweighed by the disadvantages: API learning curve as APIs involve learning concepts of the API and a sophisticated object structure, going around things that are not implemented by the API, and so on.

In this particular case, the API that I was using, the PDFSharp library, threw an exception that told exactly what was expected. This is an example of excellent API communication. It told me that I have opened a PDF Document in a mode that did not allow me to import PDFs.

So simply adding PdfDocumentOpenMode.Import solves the issue:

foreach(var reportStream in reportStreams)
{
    var pdfDoc = PdfReader.Open(reportStream, PdfDocumentOpenMode.Import);
    foreach (PdfPage page in pdfDoc.Pages)
    {
        majorDoc.Pages.Add(page);
    }
}

I've had experience with other API that throws the most obscure exceptions even at locations where it is hard to trace where your erroneous API usage originated. Or doesn't even through exceptions but does not do what is required, e.g. doesn't add pages to the main doc so it leaves it up to you to guess what went wrong: the loop was not entered for some reason, reportStreams is empty, the page elements are null, etc?

I can hardly consider fixing such an issue as a programming challenge because APIs are designed by humans, or even if they are "engineered" by humans, there are a lot of things that are just arbitrary regarding how APIs are built. Of course there are choices that makes sense more than others such as naming an API method as GetPurchaseOrders(DateTime, DateTime) rather than GetSome(DateTime, DateTime). The choices increase exponentially from here (Parameter numbers and types, overloads, type structure, complexity, error messages, returning null on failure, empty objects, etc...).

I wonder about the ways to actually "engineer" or systematize the process of "designing" an API? 

Wednesday, September 17, 2014

SharePoint CustomAction Features can be used for 3 things

Well I have a very short post because I want to note this simple fact in SharePoint customization.

Custom Action features (CustomAction XML element) is used with for both ribbon actions, site settings page section and I think list item context menus. The naming matches directly for ribbon buttons and context menus but not as much for site settings section.

And all you need to do is set the attribute Location="Microsoft.SharePoint.SiteSettings" in the CustomAction element, to have it as a site settings action. To create an item for the ribbon set Location="CommandUI.Ribbon"

Example Elements.xml of a feature:

       Id="GroupName1"
     Location="Microsoft.SharePoint.SiteSettings"
     Title="Configuration Section Title"
     Sequence="1"
     Description="blah blah"
     ImageUrl="/_layouts/Images/STSICON.GIF"
    />

      Id="customActionID1"
    GroupId="GroupName1"
    Location="Microsoft.SharePoint.SiteSettings"
    Description="LinkName"
    Title="SharePoint custom configuration page (application page)"
    Rights="MangeWeb"
    ImageUrl="/_layouts/Images/STSICON.GIF">
   
 

Thursday, August 7, 2014

Developer doing administration because of SharePoint

Even if you are on the code side of things, i.e. a programmer, you are exposed to consider a lot of things that usually belong to the administration and the infrastructure domains because a lot of what you need to use as a develop in SharePoint, relies on things that are configured by administrators.

One first initial example is that SharePoint must run within a domain, this means that you will need to create a server with Active Directory Domain Services, called ADDS. This server is called the domain controller.

Virtually everything else relies on administration related work. If you want to configure search, you will need the administrator to create a domain account for the search service. In my company developers do not have administration rights, so they must ask the administration team's help. If they are busy or not even convinced that you should do what you want to do (even on a test server), then you're out of luck. I wonder where is my negotiation skills?! Anyways, that was so annoying for me that I decided to create my own environment on my machine. Luckily I had 16GB of physical ram and an SSD. Not bad and could be used for testing purposes.

Windows Server VM, SQL Server, Domain Controller with a static IP, internet connection? Etc..

As someone whose administration skills are "me can creates adhoc network" this opens up a whole new world for me. I am learning a lot of curious things.

Wednesday, August 6, 2014

Restoring deleted Site Collections in SharePoint 2013

Useful MSDN resource: http://technet.microsoft.com/en-us/library/ff607925(v=office.15).aspx

I just learned what's the identity of a site. At least according to what Restore-SPDeletedSite knows.

This PowerShell SharePoint command is the only way to restore a deleted site collection. In SharePoint 2013 there is no UI in central administration, or even SharePoint designer as far as I have searched that allows you to do this.

To get the list of Site Collections that were deleted and are restorable, use the Get-SPDeletedSite command that will return SPDeletedSite objects.

For example (on a test server, hence http not https) gets you the following information:

WebApplicationId   : 9fa68842-c64d-493b-8102-15d4929d2fb6
DatabaseId         : dcacbbf9-719b-41b7-b7f9-526bce8100ff
SiteSubscriptionId : 00000000-0000-0000-0000-000000000000
SiteId             : b1110b1f-822b-4d70-aace-09dcba30aeca
Path               : /sites/test3
Scheme             : Http
Url                : http://msesrv30/sites/test3
DeletionTime       : 8/6/2014 8:05:41 AM

But which one of these is the site's identity? Sometimes, or a lot of times depending on how new your are to SharePoint, the terminology that is used is confusing. Anyways after a few tries someone realized that they can use the site Path as the identity while invoking the Restore-SPDeletedSite PowerShell command.

Don't forget the preceding forward-slash (/). Using sites/test3 will not work in this example.

Restore-SPDeletedSite -Identity /sites/test3

Wednesday, July 30, 2014

Complexity Management and Software Development

The details are endless, and are of the lowest business value and complete irrelevance.

One of the primary functions in the business layer of a software system uses a generated control structure. Who cares?

All those helper methods, the similarities in the code, the necessity to handle all the errors, all the different data types, the different sources of information, the conversions between the various representations, etc.

Software Development teaches developers to management complexity which is what business management is all about.

From the code's perspective, we don't care if this object denoting a person is a chief operator or a junior operator. It's just a person whose id must be entered in this field and associated with another object that is in turn associated with an period of time.

From the business perspective, we don't care if this is an object or a magic potion. I don't care that the method that processes a chief operator is exactly the same as that of a junior operator. All I care about is that I can choose both and that the system marks them as unavailable for more work, until they finish.

This is what I love about my current job. I must care for both the business perspective and the lowest levels of code details.