{"record":{"id":"0fa585f78091d6e5","repo":"LykosAI/StabilityMatrix","slug":"service-of-type-typeof-tservice-is-already-registered-for","errorCode":null,"errorMessage":"Service of type {typeof(TService)} is already registered for {typeof(T)}","messagePattern":"Service of type (.+?) is already registered for (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Avalonia/Services/ServiceManager.cs","lineNumber":34,"sourceCode":"    private readonly Dictionary<Type, T> instances = new();\n\n    // Holds scoped providers (factories)\n    private readonly ConcurrentDictionary<Type, Func<IServiceProvider, T>> scopedProviders = new();\n\n    /// <summary>\n    /// Register a new dialog view model (singleton instance)\n    /// </summary>\n    public IServiceManager<T> Register<TService>(TService instance)\n        where TService : T\n    {\n        if (instance is null)\n            throw new ArgumentNullException(nameof(instance));\n\n        lock (instances)\n        {\n            if (instances.ContainsKey(typeof(TService)) || providers.ContainsKey(typeof(TService)))\n            {\n                throw new ArgumentException(\n                    $\"Service of type {typeof(TService)} is already registered for {typeof(T)}\"\n                );\n            }\n\n            instances[instance.GetType()] = instance;\n        }\n\n        return this;\n    }\n\n    /// <summary>\n    /// Register a new dialog view model provider action (called on each dialog creation)\n    /// </summary>\n    public IServiceManager<T> Register<TService>(Func<TService> provider)\n        where TService : T\n    {\n        lock (providers)\n        {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Avalonia/Services/ServiceManager.cs#L16-L52","documentation":"ServiceManager<T>.Register<TService>(instance) throws ArgumentException when an instance or provider for TService is already registered, enforcing one registration per service type. The lock guarantees thread-safe duplicate detection.","triggerScenarios":"Calling Register<IFoo>(new Foo()) twice, or registering IFoo via Register after a Register<IFoo>(Func<T>) provider already exists for the same key in instances/providers.","commonSituations":"Double app initialization (e.g. DI setup executed on both design-time and runtime paths); registry code like LocalProviderModelManagerRegistry registering the same model manager type repeatedly across reloads.","solutions":["Guard with TryGet/ContainsKey before registering","Replace the existing registration instead of re-registering if replacement is intended","Ensure initialization code runs only once (idempotent setup)"],"exampleFix":"// before\nmanager.Register<IModelManager>(new LocalModelManager()); // may run twice\n// after\nif (!manager.IsRegistered<IModelManager>())\n    manager.Register<IModelManager>(new LocalModelManager());","handlingStrategy":"validation","validationCode":"if (manager.IsRegistered<TService>()) return manager.Get<TService>();\nmanager.Register<TService>(new TService());","typeGuard":null,"tryCatchPattern":"try { manager.Register<IFoo>(foo); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"already registered\"))\n{\n    // registration already exists; safe to ignore or fetch existing\n    existing = manager.Get<IFoo>();\n}","preventionTips":["Make DI registration idempotent (check-before-register)","Run registration code from a single bootstrap location","Use singletons at the call site instead of re-registering"],"tags":["di","duplicate-registration","dependency-injection"],"backgroundTag":"conflicting-config-options","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}