2. Service Tag

  05. Services No Comments

Service Tag

In addition to global services – which are guaranteed to be available to all clients for the entire lifetime of the application – it is also possible to register local services using Service Tags.

Local services live as part of scene or prefab assets, and are only available to clients for as long as the scene or prefab instance they are attached to remains loaded. They often also have more limited availability than global services.

Attaching a Service Tag

You can turn any component into a local service by selecting Make Service Of Type… from its context menu.
This will cause a dropdown menu to open, asking you to specify the defining types of the service.

After you’ve selected a defining type for the service, a Service Tag icon will appear in the header of the component in the Inspector. This acts as a marker to let you easily know which components have been registered as services. It also gives you access to some useful functionality when you left or right-click it, such as:

  1. Left-clicking the Service Tag opens up a menu that lets you change the defining types of the services at any time.
  2. If you click the previously selected defining type of the service again, the service tag will be removed and the component will no longer be a service.
  3. You can add more than one defining types for one component by selecting multiple options in the dropdown menu.
  4. If you right-click the Service Tag a context menu will open, giving you access to additional commands.

Removing a Service Tag

To remove a service tag, left click it, and untick all the defining type options in the menu.

Configuring Availability

If you pick the Set Availability… menu item then a dropdown menu will open, letting you choose one of the following options to define which clients will have access to the service:

  1. In GameObject – Only clients that are attached to the same GameObject as this component can receive services from it.
  2. In Children – Only clients that are attached to the same GameObject as this component, or any of its children (including nested children), can receive services from it.
  3. In Parents – Only clients that are attached to the same GameObject as this component, or any of its parents (including nested parents), can receive services from it.
  4. In Hierarchy Root Children – Only clients that are attached to the GameObject which is at the root of this component’s hierarchy, or any of the children of the root (including nested children), can receive services from it.
  5. In Scene – Only clients belonging to the same scene as this component can receive services from it.
  6. Everywhere – All clients can receive services from this component, regardless of which scene they belong to, or if they belong to any a scene at all.

Find Defining Object

Pick the Find Defining Object menu item to highlight the Object that defines the service in the Hierarchy or Project view.

If the service is defined by the ServiceAttribute, then the script asset that contains the attribute will be highlighted.

If the service is defined by a Services component, then the GameObject that contains the Services component will be highlighted.

If the service is defined by a Service Tag added via the Make Service Of Type… menu item then Find Defining Object will not appear in the menu.

Find Clients In Scenes

Pick the Find Clients In Scenes menu item to select all objects in the scene hierarchies that depend on the service.

Use Cases

Both Service Tags and Services components can be used to register local services. Since they have a lot of overlapping use cases, which one you should use by default is mostly just a matter of personal preference. That being said, here are some situations where the Service Tag could be a particularly good choice:

  1. Scenes Components – Service Tags are a particularly fitting choice for registering components found in scenes. Scenes don’t typically have a single root GameObject into which the Services component would naturally fit into. Scenes also often contain more GameObjects than prefabs do, and get changed more often over the course of development, which can make the more modular Service Tag easier to maintain.
  2. Prefab Root Components – If only want to register services from the root of a prefab, then opting to use Service Tags instead of the Services component can save you some of that precious Inspector real estate.
  3. Wrapped Objects – Service Tags can also be used to register plain C# objects using Wrappers very easily.

Best Practices

Limiting the availability of a local service to only the clients found in the hierarchy of the scene or prefab to which the service is attached to has some benefits:

  1. Synchronous Client Initialization – Having local services and their clients exist as part of the same scene or prefab hierarchy guarantees that the services will always be available when the clients are being loaded – regardless of the order in which you load your scenes and instantiate your prefabs. While Init(args) can automatically delay the initialization of components until all the services they depend on have become available, it still keeps things simpler when clients can simply be initialized synchronously.
  2. Accurate Null Argument Guard – The Init section can more accurately inform you about missing services when local services and their clients are not part of different scenes and prefabs. If the scene or prefab containing a local service is not loaded in Edit Mode, then the Null Argument Guard won’t know anything about it. While it’s possible to work around this by disabling the Null Argument Guard in Edit Mode, or by attaching an Initializer to the client and assigning Wait For Service as the Init argument field, your life will be simpler if you can skip all that.
  3. Better Inspector Integration – when the local services of a client are loaded, you’ll be able to easily ping them or select them using the Service icons found in the client’s Init section. Similarly, when all the clients of a local service are loaded, you’ll be able to easily locate all of them by selecting the Find Clients In Scenes item from the context menu of the Service icon drawn in a service component’s header

Leave a Reply

Your email address will not be published. Required fields are marked *