Contributors: 2 Thursday, October 13, 2016
Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Rip Tutorial:
Roadmap: roadmap

The Service Locator Pattern


The Service Locator design pattern is very nearly dependency injection. Like the Bridge Pattern, this pattern can be used to reference platform-dependent code from a platform-independent context. Most interestingly, this pattern relies on the singleton pattern -- everything you put into the service locator will be a defacto singleton.

// Define a service locator class in your common project
public class ServiceLocator {
    // A dictionary to map common interfaces to native implementations
    private Dictionary<object, object> _services;

    // A static instance of our locator (this guy is a singleton) 
    private static ServiceLocator _instance;
    // A private constructor to enforce the singleton
    private ServiceLocator() {
        _services = new Dictionary<object, object>();

    // A Singleton access method
    public static ServiceLocator GetInstance() {
        if(_instance == null) {
            _instance = new ServiceLocator();

        return _instance;

    // A method for native projects to register their native implementations against the common interfaces
    public static void Register(object type, object implementation) {
        _services?.Add(type, implementation);

    // A method to get the implementation for a given interface
    public static T Resolve<T>() {
        try {
            return (T) _services[typeof(T)];
        } catch {
            throw new ApplicationException($"Failed to resolve type: {typeof(T).FullName}");

//For each native implementation, you must create an interface, and the native classes implementing that interface
public interface IA {
    int DoAThing();

public interface IB {
    bool IsMagnificent();

public class IosA : IA {
    public int DoAThing() {
        return 5;

public class DroidA : IA {
    public int DoAThing() {
        return 42;

// You get the idea... 

// Then in your native initialization, you have to register your classes to their interfaces like so:
public class MainActivity : Activity
    protected override void OnCreate(Bundle bundle)

        var locator = ServiceLocator.GetInstance();
        locator.Register(typeof(IA), new DroidA());
        locator.Register(typeof(IB), new DroidB());

public partial class AppDelegate : UIApplicationDelegate
    UIWindow window;

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        window = new UIWindow(UIScreen.MainScreen.Bounds);
        window.RootViewController = new UIViewController();

        var locator = ServiceLocator.GetInstance();
        locator.Register(typeof(IA), new IosA());
        locator.Register(typeof(IB), new IosB());

        return true;

// Finally, to use your native implementations from non-native code, do as follows:
public void SomeMethodUsingNativeCodeFromNonNativeContext() {
     // Some boring code here

     // Grabbing our native implementations for the current platform
     var locator = ServiceLocator.GetInstance();
     IA myIA = locator.Resolve<IA>();
     IB myIB = locator.Resolve<IB>();

    // Method goes on to use our fancy native classes