Service Collection builder
ServicesCollectionBuilder is used to register services and build a ServiceCollection from them.
It supports registering:
- Existing service instances
- Concrete types
- Interface/type pairs
- Services discovered from a
GameObject - Services contained in a
Scene - Services exposed through
IServiceRegisterer
Managed services implementing IService are automatically tracked so that the resulting ServiceCollection can manage their lifecycle.
Methods
Section titled “Methods”public ServiceCollection Build()Creates a new ServiceCollection containing all services currently registered with the builder.
Returns
Section titled “Returns”A ServiceCollection containing the registered service instances and managed services.
Example
Section titled “Example”ServicesCollectionBuilder builder = new ServicesCollectionBuilder();
builder.Register<IMyService, MyService>();
ServiceCollection services = builder.Build();RegisterGameObject
Section titled “RegisterGameObject”public void RegisterGameObject(GameObject gameObject)Registers services found on a GameObject and its children.
The method performs two operations:
- Finds all components implementing
IServiceon the suppliedGameObjectand its children, including inactive objects, and registers them as managed services. - Finds all
IServiceRegisterercomponents directly attached to the suppliedGameObjectand allows them to register additional services with this builder.
IService components are discovered using GetComponentsInChildren<IService>(true).
IServiceRegisterer components are only searched for on the supplied GameObject; their children are not searched for IServiceRegisterer components.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
gameObject |
GameObject |
The root GameObject to scan for services. |
Example
Section titled “Example”builder.RegisterGameObject(gameObject);A typical Unity setup might look like:
GameObject├── AudioService → IService├── SaveService → IService└── UI └── UIService → IServiceAll three IService components are discovered, including services on inactive child objects.
Register Methods
Section titled “Register Methods”Register
Section titled “Register”public void Register(object service, params Type[] types)Registers an existing service instance against one or more types.
The supplied service must be assignable to every type passed in types. If it is not, an ArgumentException is thrown.
If the supplied instance implements IService, it is also added to the collection of managed services.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
service |
object |
The service instance to register. |
types |
Type[] |
The types through which the service should be registered. |
Exceptions
Section titled “Exceptions”ArgumentException
Thrown when the service is not assignable to one of the supplied types.
Example
Section titled “Example”MyService service = new MyService();
builder.Register( service, typeof(IMyService), typeof(MyService));The same instance can then be resolved through either registered type.
Note: Registration uses the type itself as the dictionary key. Registering another service against an already registered type throws because duplicate registrations are not permitted.
Register<TI, T>
Section titled “Register<TI, T>”public void Register<TI, T>() where T : TI, new()Creates a new instance of T and registers it as both TI and T.
T must:
- Implement or inherit from
TI - Have a parameterless constructor
This is a convenience overload equivalent to creating the instance manually and passing it to Register<TI, T>(T service).
Type parameters
Section titled “Type parameters”| Parameter | Constraint | Description |
|---|---|---|
TI |
— | The interface or base type used for registration. |
T |
TI, new() |
The concrete service type to instantiate. |
Example
Section titled “Example”builder.Register<IMyService, MyService>();This is equivalent to:
MyService service = new MyService();
builder.Register<IMyService, MyService>(service);Register<TI, T>
Section titled “Register<TI, T>”public void Register<TI, T>(T service) where T : TIRegisters an existing T instance as both TI and T.
Unlike the parameterless overload, this allows the service instance to be constructed manually.
Type parameters
Section titled “Type parameters”| Parameter | Constraint | Description |
|---|---|---|
TI |
— | The interface or base type used for registration. |
T |
TI |
The concrete service type. |
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
service |
T |
The service instance to register. |
Example
Section titled “Example”MyService service = new MyService();
builder.Register<IMyService, MyService>(service);The instance is registered under both:
IMyServiceMyServiceRegister<T>
Section titled “Register<T>”public void Register<T>(T service)Registers an existing service instance using its concrete type.
Type parameters
Section titled “Type parameters”| Parameter | Description |
|---|---|
T |
The type of the service instance. |
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
service |
T |
The service instance to register. |
Example
Section titled “Example”MyService service = new MyService();
builder.Register(service);The service is registered as:
MyServiceIf MyService implements IService, it is also tracked as a managed service.
Register<T>
Section titled “Register<T>”public void Register<T>() where T : new()Creates a new instance of T and registers it using its concrete type.
T must have a parameterless constructor.
Type parameters
Section titled “Type parameters”| Parameter | Constraint | Description |
|---|---|---|
T |
new() |
The service type to instantiate. |
Example
Section titled “Example”builder.Register<MyService>();This is equivalent to:
builder.Register(new MyService());RegisterSceneServices
Section titled “RegisterSceneServices”public void RegisterSceneServices(Scene scene)Registers services from every root GameObject in a Unity scene.
Each root GameObject is passed to RegisterGameObject.
This means IService components are discovered throughout the complete hierarchy of every root object in the scene.
IServiceRegisterer components are processed according to the behaviour of RegisterGameObject.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
scene |
Scene |
The Unity scene whose root objects should be scanned. |
Example
Section titled “Example”Scene scene = SceneManager.GetActiveScene();
builder.RegisterSceneServices(scene);This is useful when services are defined as components in a scene rather than registered manually.
TryGet
Section titled “TryGet”public bool TryGet(Type type, out object instance)Attempts to retrieve a registered service using its registered type.
This method does not throw when the type has not been registered.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
type |
Type |
The registered type to look up. |
instance |
object |
The registered service instance, if found. |
Returns
Section titled “Returns”true if a service was registered for the specified type; otherwise false.
Example
Section titled “Example”if (builder.TryGet(typeof(IMyService), out object instance) == true){ IMyService service = (IMyService)instance;}Managed services
Section titled “Managed services”A service is considered managed when its instance implements IService.
For example:
public class MyService : IService{}When registered, the same instance is automatically added to the builder’s managed service list.
MyService service = new MyService();
builder.Register(service);Managed services are only added once. Registering the same instance multiple times does not create duplicate managed-service entries.
The managed-service list is passed to the resulting ServiceCollection when Build is called.
What gets managed?
Section titled “What gets managed?”The following registrations automatically become managed when the instance implements IService:
builder.Register(service);builder.Register<MyService>(service);builder.Register<IMyService, MyService>(service);builder.RegisterGameObject(gameObject);builder.RegisterSceneServices(scene);IServiceRegisterer integration
Section titled “IServiceRegisterer integration”RegisterGameObject also supports components implementing IServiceRegisterer.
A registerer can register additional services through the builder:
public class MyServiceRegisterer : MonoBehaviour, IServiceRegisterer{ public void RegisterServices(ServicesCollectionBuilder builder) { builder.Register<IMyService, MyService>(); }}When the containing GameObject is registered:
builder.RegisterGameObject(gameObject);the registerer’s RegisterServices method is invoked automatically.
This allows registration logic to live alongside Unity components that own or configure the services.
Registration summary
Section titled “Registration summary”| Method | Creates instance | Registers as | Managed if IService |
|---|---|---|---|
Register(object, params Type[]) |
No | Supplied types | Yes |
Register<TI, T>() |
Yes | TI, T |
Yes |
Register<TI, T>(T) |
No | TI, T |
Yes |
Register<T>(T) |
No | T |
Yes |
Register<T>() |
Yes | T |
Yes |
RegisterGameObject(GameObject) |
No | Discovered/registerer-defined types | Yes |
RegisterSceneServices(Scene) |
No | Discovered/registerer-defined types | Yes |
Typical usage
Section titled “Typical usage”A complete setup might look like:
ServicesCollectionBuilder builder = new ServicesCollectionBuilder();
builder.Register<ILogger, GameLogger>();builder.Register(new SaveService());
builder.RegisterSceneServices(SceneManager.GetActiveScene());
ServiceCollection services = builder.Build();The resulting ServiceCollection contains all manually registered services as well as services discovered from the scene.
Registration rules
Section titled “Registration rules”- A type can only be registered once.
- Registering a type that already exists throws an
ArgumentExceptiondue to duplicate dictionary keys. Register(object, params Type[])validates that the service is assignable to every supplied type.- Services implementing
IServiceare automatically tracked as managed services. - The same managed service instance is only tracked once.
RegisterGameObjectsearches child objects forIService, including inactive children.RegisterGameObjectonly searches the supplied object itself forIServiceRegisterer.RegisterSceneServicesprocesses every rootGameObjectin the scene.Build()creates aServiceCollectionfrom the registrations accumulated so far.- The builder itself does not expose a typed
Get<T>(); useTryGet(Type, out object)when querying the builder directly.