stride3d/stride · error · InvalidOperationException

A service of the same type has already been registered.

Error message

A service of the same type has already been registered.

What it means

ViewModelServiceProvider keeps a flat list of services and enforces one instance per concrete type. RegisterService throws InvalidOperationException when a service of the same exact runtime type is already registered.

Solutions

  1. Check ServiceRegistered/existing services before registering, or call RegisterService only once per type
  2. Replace the existing instance instead of re-registering (remove then add, or design the provider API to allow replacement)
  3. Deduplicate the service list passed to the ViewModelServiceProvider constructor

Example fix

// before
provider.RegisterService(new MyService());
provider.RegisterService(new MyService()); // throws
// after
if (provider.TryGet<MyService>() == null) provider.RegisterService(new MyService());
Defensive patterns

Strategy: validation

Validate before calling

bool alreadyRegistered = provider.TryGet(service.GetType()) != null;
if (!alreadyRegistered) provider.RegisterService(service);

Try / catch

try { provider.RegisterService(service); }
catch (InvalidOperationException) { /* same-type service already present; keep existing */ }

Prevention

When it happens

Trigger: Calling RegisterService(obj) twice with objects of the same runtime type; the constructor (which registers initial services) also routes through RegisterService, so passing two instances of one type to the constructor triggers it too.

Common situations: Re-registering a service after provider setup; constructor invoked with a duplicated service; registering a service that the base/provider already added (e.g. the view model itself).

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/8b462212a9521845. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs:57

            {
                RegisterService(service);
            }
        }
    }

    /// <inheritdoc/>
    public event EventHandler<ServiceRegistrationEventArgs>? ServiceRegistered;

    /// <inheritdoc/>
    public event EventHandler<ServiceRegistrationEventArgs>? ServiceUnregistered;

    /// <inheritdoc/>
    public void RegisterService(object service)
    {
        ArgumentNullException.ThrowIfNull(service);

        if (services.Any(x => x.GetType() == service.GetType()))
            throw new InvalidOperationException("A service of the same type has already been registered.");

        services.Add(service);
        ServiceRegistered?.Invoke(this, new ServiceRegistrationEventArgs(service));
    }

    /// <inheritdoc/>
    public void UnregisterService(object service)
    {
        ArgumentNullException.ThrowIfNull(service);

        if (services.Remove(service))
        {
            ServiceUnregistered?.Invoke(this, new ServiceRegistrationEventArgs(service));
        }
    }

    /// <inheritdoc/>
    public object? TryGet(Type serviceType)

View on GitHub (pinned to 96fad776d2)