BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Universal Programs and API Contracts

Universal Programs and API Contracts

Bookmarks

Historically, creating universal or “run anywhere” applications meant restricting yourself to the lowest common denominator. New features can’t be used until all devices support it, which may be never depending on your customer base. In the Windows 10 vision, that isn’t going to be the case.

When talking about universal applications, there are three “adaptive dimensions” that Microsoft is focusing on:

  • Version adaptive: Features that don’t exist in version N but they do in version N+1.
  • Device family adaptive: Features that only exist on some devices.
  • Form factor adaptive: Also known as responsive design.

Conceptually we don’t have device specific APIs.

While it will take some time for the APIs to be implemented across the entire ecosystem, the goal is to ensure that there is no longer the concept off a device specific API in the Windows 10 platform.

Historic Techniques

  • C++: LoadLibrary/GetProcAddress or CoCreateInstance/QueryInterface
  • .NET: ‘dynamic’, System.Object, and Reflection
  • JavaScript: Checking for undefined

These techniques are hard to use because there is little or no compile time diagnostics. Any mistakes are revealed at runtime rather, often only on a subset of the target devices.

Problems with WinRT and Portable Class Libraries

WinRT lacked a unified API. For any given class, developers would have to check the platform and OS version for every method before taking a dependency on it. The confusion this created was almost worse than having complete different APIs.

An attempt to deal with this situation was made using portable class libraries. But with just two versions of desktop, phone, and XBox, developers already had 2^6-1 different possible combinations. This discouraged many developers from even attempting to offer cross-platform libraries.

Adaptive Code and the Universal API

Under the universal model, 85% of APIs are available across all device families. If you look at only the top 1000 applications, 96.2% of the APIs are universally available. This means that most application won’t need adaptive code.

Now it needs to be noted that just because an API is available doesn’t mean it will actually work. For example, the XBox has the printer APIs even though it is impossible to attach a printer to a XBox. If you attempt to get the default printer it will fail by returning null, just like a desktop computer without a printer.

Think features, not devices

Some APIs are considered to be “optional” and are not available on all devices. This may lead developers to check for specific platforms or versions, which is the wrong thing to do. Just because the API isn’t available today doesn’t mean it won’t be added in the next update.

Instead of version checks, developers should use this family of functions from any language:

ApiInformation.IsXxxPresent(…)

This check will work for types, methods, properties, events, and enumeration values.

API Contracts

An API Contract is a named and versioned set of functionality. API Contracts are atomic; any device taking on an API Contract must implement the whole contract. Microsoft is not allowing its teams to selectively take classes and methods that they want while leaving others behind.

All WinRT APIs are part of a specific API Contract. To find out if a device has as a given API Contract, you can use this function:

ApiInformation.IsApiContractPresent(name, majorVersion, minorVersion)

Adaptive Coding Pattern

if (ApiInformation.IsWritablePropertyPresent("Windows.Networking.HttpRequest.SecureSendRequired"))
{
    client.SecureSendRequired = true;
}

This pattern only works because the .NET Native compiler will silently remove the line that refers to the non-existent property. If the code were JIT-compiled on the device, it would fail due to the missing property.

Device Families

A Device Family is defined by the set of API Contracts that the device choose to implement.

It is no longer to think in terms of, “This API is phone specific”. Rather, you should say, “Phones support this API” because there is no such thing as an API that is restricted to a specific platform. At worst, the API simply hasn’t been offered yet in other device families.

For more information on API Contracts, watch the Channel 9 presentation API Contracts (or How I Learned to Stop Checking OS Versions and Love Feature Detection).

Rate this Article

Adoption
Style

BT