VContainer integration
VContainer is a popular DI library for Unity.
If VContainer is installed in your project, the VITALROUTER_VCONTAINER_INTEGRATION
compiler switch will be automatically enabled, and the following functions will be available.
RegisterVitalRouter
The RegisterVitalRouter
method is added to the IContainerBuilder of VContainer.
using VContainer;
using VitalRouter;
using VitalRouter.VContainer;
// VContaner's configuration
public class GameLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.RegisterVitalRouter(routing =>
{
routing.Map<FooPresenter>(); // < Register routing plain class
// Or, use MonoBehaviour instance with DI
routing.MapComponent(instance);
// Or, use MonoBehaviour in the scene
routing.MapComponentInHierarchy<MyRoutesComponent>();
// Or, use MonoBehaviour from prefab
routing.MapComponentInNewPrefab(prefab);
});
}
}
As in this example, the type with [Routes]
is registered in the Action passed as an argument. The type specified here is registered in the DI container at the same time, and when the DI scope is created, MapTo is automatically called for the Router linked to the DI container, and when the scope is destroyed, Unmap is automatically called.
By default, when RegisterVitalRouter is called, Router
is newly registered in the DI container.
If you want to use an existing Router instance (or Router.Default), register it as follows.
builder.RegisterInstance(Router.Default);
builder.RegisterVitalRouter(routing =>
{
// ...
});
Ordering
By setting the Ordering
property, you can set the order control for the Routers you register here.
builder.RegisterVitalRouter(routing =>
{
// ...
routing.Ordering = CommandOrdering.Sequential;
// ...
});
For more information about CommandOrdering
, please refer to the Sequential control section.
Filters
You can use the Filters
property to add Interceptors
that apply to this scope.
builder.RegisterVitalRouter(routing =>
{
// ...
routing.Filters.Add<Filter1>();
// ...
});
It is convenient to set up the Filter via DI, as this automates the instantiation of the Interceptor and dependency resolution.
For more information about Interceptors, please refer to the Interceptor section.
Resolving
If RegisterVitalRouter
is set, the Router and its interface, ICommandPublisher
and ICommandSubscriber
can be retrieved from the DI container.
class HogeController
{
readonly ICommandPublisher publisher;
// Resolve `ICommandPublisher`
public HogeController(ICommandPublisher publisher)
{
this.publisher = publisher;
}
public void DoSomething()
{
publisher.PublishAsync(new FooCommand { X = 1, Y = 2 }).Forget();
}
}
public class HogePresenter
{
// Resolve `ICommandSubscribable`
public FooController(ICommandSubscribable subscribable)
{
subscribable.Subscribe((cmd, ctx) => { /* ... */ });
}
}
Child scope
VContainer can create child scopes at any time during execution.
RegisterVitalRouter
inherits the Router defined in the parent.
For example,
public class ParentLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.RegisterVitalRouter(routing =>
{
routing.Map<PresenterA>();
});
builder.Register<ParentPublisher>(Lifetime.Singleton);
}
}
public class ChildLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.RegisterVitalRouter(routing =>
{
routing.Map<PresenterB>();
});
builder.Register<MyChildPublisher>(Lifetime.Singleton);
}
}
- When an instance in the parent scope publishes used
ICommandPublisher
, PresenterA and PresenterB receive it. - When an instance in the child scope publishes
ICommandPublisher
, also PresenterA and PresenterB receives.
If you want to create a dedicated Router for a child scope, do the following.
builder.RegisterVitalRouter(routing =>
{
+ routing.Isolated = true;
routing.Map<PresenterB>();
});