05 October 2012

NFC payments - it's not for you!

NFC payment terminals are becoming more common and all the credit/debit cards in my wallet have supported NFC for about 6 months which is great as it's much more convenient, especially for buying a coffee or lunch.

NFC and by extension RFID are nothing new - I think I first saw a dog getting an RFID implant put in on Blue Peter in the early 90's and next year NFC will have run the London Underground for 10 years in the form of the Oyster card. It's taken a long time for the banks to warm to this technology - maybe because there's a lot of security protocols to be determined and a lot of liability sums to be calculated etc.

I've had a Google Nexus S for about 18 months which was, from what I've read, the first NFC-enabled handset available in the UK. When I bought it Google were yet to release Wallet, their NFC payment app for Android, but there weren't many NFC payment terminals available so it wasn't that much of a big deal.

The Wallet logo is quite a clever echo of the NFC payment logo

Wallet has since been released in the US and is supported by all the major credit card companies but that's where the good news ends. It seems Google have deals with particular networks, Sprint being the main one, meaning that even if you have an NFC-enabled Android handset you can only use Wallet if you're on one of the approved networks. What's worse is that it isn't available in the UK and there's no word from Google on when or if it will be.

What is particularly odd is that the Nexus 7 has no such restriction. I can only assume this is because it has no GSM modem so there is no deal to be made with a mobile network. This is particularly frustrating because I can see that, if you buy a phone from a particular carrier and that carrier doesn't have a deal with Google, you won't get Wallet but I bought my Nexus S SIM free from Carphone Warehouse so the phone itself has no network affiliation and yet I still can't use Wallet.

What is quite interesting and may shine some light on the whole delay in Wallet getting to the UK is the release of Quick Tap from Barclaycard and Orange. Although Orange sell 10 NFC-enabled handsets only 2 of them are "Quick Tap ready", both of which happen to be the Galaxy SIII, probably their most popular and expensive handset apart from the iPhone. I doubt there's technically anything special about the SIII that means it can be used for payments where the other handsets can't - all the others are cheaper so my guess is it's entirely about forcing people to buy a more expensive handset.

If the other UK networks and card companies are doing similar deals it's no wonder a service like Wallet is unavailable as there is money to be made and phones to be sold. All in all it's pretty rubbish for the early adopter and the consumer in general.

Surely the fact that a phone is PIN protected and the NFC is not always on actually makes it a more secure way of implementing NFC payments. People can't skim your phone the way they can the cards in your actual wallet.

Guess I'll just have to wait and see where this farcical endeavour goes. In the meantime I'll look forward to an Oyster app (which would be pretty ace) and scanning some NFC business cards, I suppose. Whoopee!

20 March 2012

Interfaces and IoC

If you want to use inversion of control, unit testing and adhere to SOLID principals in your C# code this often means you have a lot of interfaces. Core considerations when dealing with interfaces are things like:

  • Where should the interface be defined – alongside the main implementation or in a separate assembly?
  • Should the interface be generic or not?
  • Am I breaking interface segregation principal?

The one that sometimes falls by the wayside is:

  • Does the the interface definition match my intended usage?

Example

A trivial example of this might be where you have a database containing a Log table of messages from an application where each has an ID of some kind, type, source, message and date/time recorded. The interface for the data access to this table might be:

public interface ILogRepository { IEnumerable<Log> GetLogs(); }

Innocuous enough however what if all our usages of this interface and method require that the resultant IEnumerable is ordered by the recorded time of the log message. IEnumerable alone doesn’t guarantee anything about the order and reordering the output at each point of use would be very inefficient, not to mention that the database would likely be a much better place to perform the ordering action.

Attempt 1 – Be more descriptive

The simplest option is simply to bake the ordering information in to the interface definition e.g.

public interface ILogRepository { IEnumerable<Log> GetLogsOrderedByDate(); }

This way we are clear at the point of implementation and the point of use about what the ordering of the items should be. Of course, renaming a method still doesn’t guarantee the result will be ordered correctly but at least if an ordering is missing you have the additional information in the definition about what the correct order should be.

The major problem with this option is that we head towards potentially violating the Open/Closed principal where our API should be open for extension but closed for modification. If we need to change the order log items are returned then we have to rename the method (violating OCP) or add a new method which specifies a different ordering potentially making the original completely redundant in the codebase.

Attempt 2 – Expose IQueryable instead

Another option is to swap from using IEnumerable to using IQueryable and allow the calling code to specify its own ordering e.g.

public interface ILogRepository { IQueryable<Log> GetLogs(); }

...

var logs = logRepo.GetLogs().OrderBy(l => l.DateTime);

This method would be more efficient, always performing the ordering in the database, but with this option we have to repeat the OrderBy part at every point of use to ensure our ordering will be correct. This gives us flexibility but isn’t particularly DRY and may be difficult to change.

It’s also somewhat of a leaky abstraction as we’re spilling data access innards into our other layers and losing control of the queries being executed on our database – calling code can do more with  IQueryable than specify an order which may not be desirable.

Attempt 3 – Allow ordering to be passed in

This is somewhat similar to option 2 however by allowing order to be passed in we can use a specified default ordering while also giving the calling code the ability to override it if necessary without exposing the all-powerful IQueryable.

public interface ILogRepository 
{
   IEnumerable<Log> GetLogs<TKey>(Expressions<Func<Log, TKey>> ordering);
}

Of course this option still has the potential for a lot of repetition of desired ordering and OCP may rear its head again if we need to expose some other IQueryable feature in a similar controlled fashion. Another undesirable feature of this method is that the specified ordering cannot be easily validated, much like with option 2 it may provide the caller with too much power.

Attempt 4 – Return IOrderedEnumerable

An interesting option is amending the interface definition so that the method returns IOrderedEnumerable instead of plain IEnumerable e.g.

public interface ILogRepository { IOrderedEnumerable<Log> GetLogs(); }

A very slight tweak to the definition with no specific ordering defined in the API but it provides a cue to the calling code that an ordering is being applied, should it care, and also makes it difficult for the interface implementation to accidentally miss out the ordering.

Obviously with this option we return to the problem of there being no particular guarantee of the specific ordering being applied not to mention it being quite tricky to return IOrderedEnumerable in the first place.

Alternatives?

Perhaps a better question than:

  • Does the the interface definition match my intended usage?

would be:

  • Can I describe my intended usage sufficiently with an interface?

It’s difficult to define this, and many other kinds of behaviours, using interfaces alone. A better approach in this case would probably be to not interface this class out at all and have the business code expect an instance of the concrete type as its dependency thus providing a guarantee of order. The class would still be abstracted from the backing store such that it can itself be tested e.g.

// Data access code
internal interface ILogStore { IQueryable<Log> Logs { get; } }

public class LogRepository
{
   private ILogStore _store;   

   public LogRepository() : this(null) {}

   internal LogRepository(ILogStore store)
   {
      _store = store ?? new DatabaseLogStore();
   }

   public IEnumerable<Log> GetLogs()
   {
      return _store.Logs.OrderBy(l => l.DateTime);
   }
}

// Business code
public class LogReader
{
   private LogRepository _logRepo;

   public LogReader(LogRepository logRepo)
   {
      if (logRepo == null) throw new ArgumentNullException("logRepo");
      _logRepo = logRepo;
   }

   ...
}