Skip to content

Dependency Injection

This example shows how to integrate Lexis with dependency injection containers.

Interface-Based Design

Lexis provides ILocalizationService for DI scenarios:

csharp
public interface ILocalizationService
{
    Locale CurrentLocale { get; }
    IReadOnlyList<Locale> AvailableLocales { get; }
    event Action<Locale> OnLocaleChanged;

    void Initialize(LocalizationSettings settings = null);
    void SetLocale(string localeCode);
    string Get(string key, params object[] args);
    bool HasTranslation(string key);
}

Basic DI Setup

csharp
using Lexis;
using UnityEngine;

public class DISetup : MonoBehaviour
{
    void ConfigureServices(IServiceContainer container)
    {
        // Create service with custom settings
        var settings = Resources.Load<LocalizationSettings>("CustomSettings");
        var service = new LocalizationService();
        service.Initialize(settings);

        // Register with DI container
        container.RegisterInstance<ILocalizationService>(service);

        // Connect to static facade (optional, for convenience)
        Localization.Service = service;
    }
}

Zenject Integration

Installer

csharp
using Lexis;
using UnityEngine;
using Zenject;

public class LocalizationInstaller : MonoInstaller
{
    [SerializeField] private LocalizationSettings settings;

    public override void InstallBindings()
    {
        // Create and initialize service
        var service = new LocalizationService();
        service.Initialize(settings);

        // Bind as singleton
        Container.Bind<ILocalizationService>()
            .FromInstance(service)
            .AsSingle();

        // Optional: connect to static facade
        Container.Bind<IInitializable>()
            .To<LocalizationFacadeConnector>()
            .AsSingle();
    }
}

public class LocalizationFacadeConnector : IInitializable
{
    private readonly ILocalizationService _service;

    public LocalizationFacadeConnector(ILocalizationService service)
    {
        _service = service;
    }

    public void Initialize()
    {
        Localization.Service = _service;
    }
}

Consumer

csharp
using Lexis;
using UnityEngine;
using Zenject;

public class LocalizedUI : MonoBehaviour
{
    private ILocalizationService _localization;

    [Inject]
    public void Construct(ILocalizationService localization)
    {
        _localization = localization;
    }

    void Start()
    {
        UpdateUI();
        _localization.OnLocaleChanged += _ => UpdateUI();
    }

    void UpdateUI()
    {
        titleText.text = _localization.Get("ui.title");
    }
}

VContainer Integration

Registration

csharp
using Lexis;
using VContainer;
using VContainer.Unity;

public class GameLifetimeScope : LifetimeScope
{
    [SerializeField] private LocalizationSettings settings;

    protected override void Configure(IContainerBuilder builder)
    {
        // Create service
        var service = new LocalizationService();
        service.Initialize(settings);

        // Register
        builder.RegisterInstance<ILocalizationService>(service);

        // Entry point for facade connection
        builder.RegisterEntryPoint<LocalizationEntryPoint>();
    }
}

public class LocalizationEntryPoint : IStartable
{
    private readonly ILocalizationService _service;

    public LocalizationEntryPoint(ILocalizationService service)
    {
        _service = service;
    }

    public void Start()
    {
        Localization.Service = _service;
    }
}

Consumer

csharp
using Lexis;
using VContainer;

public class LocalizedPresenter
{
    private readonly ILocalizationService _localization;
    private readonly IView _view;

    [Inject]
    public LocalizedPresenter(ILocalizationService localization, IView view)
    {
        _localization = localization;
        _view = view;
    }

    public void Initialize()
    {
        _view.SetTitle(_localization.Get("ui.title"));
    }
}

Testing with Mock

csharp
using Lexis;
using NUnit.Framework;
using NSubstitute;

public class LocalizedUITests
{
    [Test]
    public void UpdateUI_SetsCorrectTitle()
    {
        // Arrange
        var mockService = Substitute.For<ILocalizationService>();
        mockService.Get("ui.title").Returns("Test Title");

        var ui = new LocalizedUI(mockService);

        // Act
        ui.UpdateUI();

        // Assert
        Assert.AreEqual("Test Title", ui.TitleText);
    }
}

Non-MonoBehaviour Classes

csharp
using Lexis;

public class GameUI
{
    private readonly ILocalizationService _localization;

    public GameUI(ILocalizationService localization)
    {
        _localization = localization;
    }

    public string GetTitle() => _localization.Get("game.title");

    public string GetFormattedScore(int score)
    {
        return _localization.Get("score.format", score);
    }
}

Best Practices

  1. Use interfaces - Depend on ILocalizationService, not concrete types
  2. Initialize once - Create and configure the service at startup
  3. Connect facade optionally - Useful for components that can't use DI
  4. Dispose properly - Call Dispose() on the service when done
  5. Mock for tests - Use the interface to create test doubles

Professional Unity Development Tools