dotnet/wpf · error · ArgumentException

SR.ServiceTypeAlreadyAdded

Error message

SR.ServiceTypeAlreadyAdded

What it means

ServiceProviders.AddService throws ArgumentException(SR.ServiceTypeAlreadyAdded) when AddService is called for a serviceType that is already registered with a different service instance. The service map is write-once per type. This prevents silently replacing an already-published service object.

Solutions

  1. Check GetService(serviceType) for null before calling AddService and skip if already present.
  2. Register each service type exactly once during initialization.
  3. Use the same service instance if re-registration is intentional (the check passes when the stored instance equals the new one).
  4. Catch ArgumentException and treat it as 'already registered' if idempotent registration is desired.

Example fix

// before
providers.AddService(typeof(IMyService), new MyService());
providers.AddService(typeof(IMyService), new MyService()); // throws
// after
if (providers.GetService(typeof(IMyService)) == null)
    providers.AddService(typeof(IMyService), new MyService());
Defensive patterns

Strategy: validation

Validate before calling

bool canAdd = providers.GetService(typeof(IMyService)) == null;

Type guard

null

Try / catch

try { providers.AddService(typeof(IMyService), svc); }
catch (ArgumentException) { /* already registered with a different instance */ }

Prevention

When it happens

Trigger: Calling AddService(typeof(X), serviceA) and then AddService(typeof(X), serviceB) on the same ServiceProviders instance; re-registering a service during a second initialization pass; multiple components each attempting to register the same service type.

Common situations: Double initialization of a designer/serializer context (e.g. adding the same service to an EditorContext twice); shared service providers reused across parse/serialize operations; DI-style code assuming Add behaves like a dictionary indexer set.

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 dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/5f931084e3a5c3e2. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Markup/ServiceProviders.cs:47

        #endregion

        /// <summary>
        /// Add a new service
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="service"></param>
        public void AddService(Type serviceType, Object service)
        {
            ArgumentNullException.ThrowIfNull(serviceType);
            ArgumentNullException.ThrowIfNull(service);

            if (!_objDict.ContainsKey(serviceType))
            {
                _objDict.Add(serviceType, service);
            }
            else if (_objDict[serviceType] != service)
            {
                throw new ArgumentException(SR.ServiceTypeAlreadyAdded, nameof(serviceType));
            }
        }

        private Dictionary<Type,Object> _objDict = new Dictionary<Type,Object>();
    }
}

View on GitHub (pinned to 81131a70a4)