{"record":{"id":"13843234b35e46f7","repo":"stride3d/stride","slug":"service-is-already-registered-with-this-type","errorCode":null,"errorMessage":"Service is already registered with this type","messagePattern":"Service is already registered with this type","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/ServiceRegistry.cs","lineNumber":74,"sourceCode":"        }\n\n        return null;\n    }\n\n    /// <inheritdoc />\n    /// <remarks>\n    /// This implementation triggers the <see cref=\"ServiceAdded\"/> event after a service is successfully added.\n    /// </remarks>\n    public void AddService<T>(T service)\n        where T : class\n    {\n        ArgumentNullException.ThrowIfNull(service);\n\n        var type = typeof(T);\n        lock (registeredService)\n        {\n            if (!registeredService.TryAdd(type, service))\n                throw new ArgumentException(\"Service is already registered with this type\", nameof(type));\n        }\n        OnServiceAdded(new ServiceEventArgs(type, service));\n    }\n\n    /// <inheritdoc />\n    /// <remarks>\n    /// This implementation triggers the <see cref=\"ServiceRemoved\"/> event after a service is successfully removed.\n    /// If the service type is not found, this method does nothing.\n    /// </remarks>\n    public void RemoveService<T>()\n        where T : class\n    {\n        var type = typeof(T);\n        object? oldService;\n        lock (registeredService)\n        {\n            registeredService.Remove(type, out oldService);\n        }","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/ServiceRegistry.cs#L56-L92","documentation":"ServiceRegistry.AddService registers a service instance per service type in a dictionary; only one instance per type is allowed. Adding a second service for the same typeof(T) fails the TryAdd and throws this ArgumentException.","triggerScenarios":"Calling AddService<T>(T) when an instance of T (the exact service type) is already registered, e.g. double-initialization of Game, running processor setup twice, or two tests sharing a registry without cleanup.","commonSituations":"Unit tests reusing a shared ServiceRegistry across test cases without RemoveService; app startup code that registers a service both in a bootstrapper and in game initialization.","solutions":["Call RemoveService<T>() (or dispose the registry) before re-adding the service","Use GetOrCreate<T>() to fetch the existing instance instead of AddService","Fix double initialization so AddService runs only once per type"],"exampleFix":"// before\nservices.AddService<ICameraProcessor>(cameraProcessor);\nservices.AddService<ICameraProcessor>(cameraProcessor); // throws\n// after\nif (services.GetInstance<ICameraProcessor>() == null)\n    services.AddService<ICameraProcessor>(cameraProcessor);","handlingStrategy":"validation","validationCode":"if (registry.GetInstance<T>() != null)\n    return registry.GetInstance<T>(); // already registered, reuse it\nregistry.AddService<T>(service);","typeGuard":null,"tryCatchPattern":"try { registry.AddService(service); }\ncatch (ArgumentException e) when (e.Message.Contains(\"already registered\"))\n{ service = registry.GetInstance<T>(); } // fall back to existing instance","preventionTips":["Prefer GetOrCreate<T>() over AddService for idempotent startup","Call RemoveService<T>() in test teardown when sharing a registry","Initialize services in exactly one place"],"tags":["service-registry","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"}