{"record":{"id":"8b462212a9521845","repo":"stride3d/stride","slug":"a-service-of-the-same-type-has-already-been-registered","errorCode":null,"errorMessage":"A service of the same type has already been registered.","messagePattern":"A service of the same type has already been registered\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs","lineNumber":57,"sourceCode":"            {\n                RegisterService(service);\n            }\n        }\n    }\n\n    /// <inheritdoc/>\n    public event EventHandler<ServiceRegistrationEventArgs>? ServiceRegistered;\n\n    /// <inheritdoc/>\n    public event EventHandler<ServiceRegistrationEventArgs>? ServiceUnregistered;\n\n    /// <inheritdoc/>\n    public void RegisterService(object service)\n    {\n        ArgumentNullException.ThrowIfNull(service);\n\n        if (services.Any(x => x.GetType() == service.GetType()))\n            throw new InvalidOperationException(\"A service of the same type has already been registered.\");\n\n        services.Add(service);\n        ServiceRegistered?.Invoke(this, new ServiceRegistrationEventArgs(service));\n    }\n\n    /// <inheritdoc/>\n    public void UnregisterService(object service)\n    {\n        ArgumentNullException.ThrowIfNull(service);\n\n        if (services.Remove(service))\n        {\n            ServiceUnregistered?.Invoke(this, new ServiceRegistrationEventArgs(service));\n        }\n    }\n\n    /// <inheritdoc/>\n    public object? TryGet(Type serviceType)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Check ServiceRegistered/existing services before registering, or call RegisterService only once per type","Replace the existing instance instead of re-registering (remove then add, or design the provider API to allow replacement)","Deduplicate the service list passed to the ViewModelServiceProvider constructor"],"exampleFix":"// before\nprovider.RegisterService(new MyService());\nprovider.RegisterService(new MyService()); // throws\n// after\nif (provider.TryGet<MyService>() == null) provider.RegisterService(new MyService());","handlingStrategy":"validation","validationCode":"bool alreadyRegistered = provider.TryGet(service.GetType()) != null;\nif (!alreadyRegistered) provider.RegisterService(service);","typeGuard":null,"tryCatchPattern":"try { provider.RegisterService(service); }\ncatch (InvalidOperationException) { /* same-type service already present; keep existing */ }","preventionTips":["Register services exactly once, in the view model constructor","Check TryGet(type) before re-registering","Design service instances as singletons per provider to avoid accidental duplicates"],"tags":["dotnet","dependency-injection","duplicate-registration"],"backgroundTag":"conflicting-config-options","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}