Giter Club home page Giter Club logo

servicelocator's Introduction

Service Locator Example

This is a working example of the Service Locator pattern for use within the Unity game engine. This repository is provided as usable code, but also as an example of the Service Locator pattern.

The Service Locator Pattern

While Wikipedia's Service Locator Page provides a good overview, I want to focus on the following:

  • Why you should use this pattern over Singletons.
  • How to use this pattern.
  • How not to write services or other singleton code.

Things I won't touch on here:

  • Dependency Injection and its benefits
  • Disadvantages, why this is an 'anti-pattern', etc.

Stop Writing Singletons

One of the trickiest aspects of development is figuring out how to 'get access to the thing'. Frequently developers need one instance of an important item. They write code to allow this one instance to be accessible in their code and access it via MyThing.Instance.

This pattern works but you are really stuck with that one item. And you have to write that .Instance code in each class that uses it. This gets worse if you work on a team and everyone writes their singletons slightly differently. And don't ever suddenly need more than one of the item.

Locating of Services

Enter Service Locator. In essence, this is an uber-Singleton. A singleton to rule them all. It provides a consistent system you can use to provide access to all your Singletons, which, in this enlightened new world we'll call Services. Yep, most of the time the Service in Service Locator is really just a Singleton. But I guess Singleton Locator doesn't have the same ring to it.

Installation

This repo is a Unity Package. You can install from disk or from Github via Package Manager. There are two sample projects to help give an example of usage. These can also be imported via Package Manager.

Using Service Locator

There are two steps involved to using services: registering them, and using them.

Registering Services

You can register a service by either registering the service directly, or by registering a 'factory' method that will create the service when it is first accessed. Do this upon startup of your game.

void InitializeOnStartup()
{
  // Create and register the service immediately.
  ServiceLocator.Register<MyService>(new MyService());
  // Or register the service now, and let it be made later.
  ServiceLocator.RegisterFactory<MyService>(() => new MyService());
  ... register more services here...
}

Using Services

When using a service, you use ServiceLocator.Get<T>() to get the item.

private MyService _myService;

void OnStartup()
{
    _myService = ServiceLocator.Get<MyService>();
    // ... use your service to do service-y things.
}

And that's it! You now have a system that is just as easy to use as a singleton, but with less code!

Super Secret Pro Tips

I probably shouldn't be telling you this, but here are some extra cool things you can do with this pattern.

Service-ception

Frequently you may have services that depend upon services. When these dependencies exist, its quite simple to just use service locator to fetch them:

void IntializeOnStartup()
{
    ServiceLocator.RegisterFactory(() => new MyService());
    ServiceLocator.RegisterFactory(() => new MyOtherService(ServiceLocator.Get<MyService>());
}

This allows your dependencies to all initialize lazily and as needed by your other services. Cool!

Interfaces instead of types

Another pro tip is that you can use interfaces to register your services and register different services for different reasons.

void InitializeOnStartup()
{
    IStoreService storeService = null;
    if(Application.Platform == RuntimePlatform.iOS)
    {
        storeService = new IOSStoreProvider();
    else if(Application.Platform == RuntimePlatform.Android)
    {
        storeService = new AndroidStoreProvider();
    }
    else{
        storeService = new DefaultStoreProvider();
    }
    ServiceLocator.Register<IStoreProvider>(storeService);
}

This works great for unit tests as well!

How Not To Write Services Code

Frequently you may see code that looks like this:

void DoThing()
{
  var myValue = GetValue();
  MyService.Instance.UpdateValue(myValue);
}

void DoAnotherThing()
{
 var otherValue = GetOtherValue();
 MyService.Instance.UpdateValue(myValue);
}

If for some reason we need to update our class and clean up the code, we have a number of locations where we're using this file. Instead create a member variable so that the usage of the service isn't part of requesting the service:

private MyService _myService;

void Init()
{
  _myService = ServiceLocator.Get<MyService>();
}

void DoThing()
{
  var myValue = GetValue();
  _myService.UpdateValue(myValue);
}

void DoAnotherThing()
{
 var otherValue = GetOtherValue();
 _myService.UpdateValue(myValue);
}

servicelocator's People

Contributors

robotron2084 avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.