{"record":{"id":"b9788f3d7790a7b5","repo":"stride3d/stride","slug":"multiple-services-match-the-given-type","errorCode":null,"errorMessage":"Multiple services match the given type.","messagePattern":"Multiple services match the given type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs","lineNumber":84,"sourceCode":"        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)\n    {\n        ArgumentNullException.ThrowIfNull(serviceType);\n\n        object? serviceFound = null;\n\n        foreach (var service in services.Where(serviceType.IsInstanceOfType))\n        {\n            if (serviceFound != null)\n                throw new InvalidOperationException(\"Multiple services match the given type.\");\n\n            serviceFound = service;\n        }\n\n        return serviceFound ?? parentProvider?.TryGet(serviceType);\n    }\n\n    /// <inheritdoc/>\n    public T? TryGet<T>() where T : class\n    {\n        return TryGet(typeof(T)) as T;\n    }\n\n    /// <inheritdoc/>\n    public object Get(Type serviceType)\n    {\n        var result = TryGet(serviceType);\n        return result ?? throw new InvalidOperationException(\"No service matches the given type.\");","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs#L66-L102","documentation":"Thrown by ViewModelServiceProvider.TryGet when more than one registered service is an instance of the requested serviceType. TryGet is meant to resolve a single unambiguous service; the provider's services list is not keyed by type, so a request matching multiple registrations is ambiguous and cannot be answered, hence the InvalidOperationException. It fires when the same service type (or compatible base/interface) was registered twice.","triggerScenarios":"Registering two services where both are instances of serviceType (e.g. one type implementing two registered interfaces, or a subclass registered alongside its base), then calling TryGet/Get for the shared type.","commonSituations":"Registering an interface and a base class that both match one instance; duplicate services registered under related types; parent provider + local provider ambiguities resolved in the loop before the parent fallback.","solutions":["Register each service under exactly one unambiguous type and query for the most specific type","Remove the redundant registration that makes the match ambiguous","Iterate the raw service list yourself if you truly need multiple matches"],"exampleFix":"// before\nprovider.RegisterService(myServiceImpl);      // matches IMyService and MyBase\nprovider.RegisterService((MyBase)myServiceImpl); // ambiguous\nvar svc = provider.TryGet(typeof(IMyService)); // throws\n// after\nprovider.RegisterService(myServiceImpl); // register once\nvar svc = provider.TryGet(typeof(IMyService));","handlingStrategy":"validation","validationCode":"var candidates = new List<object>();\nforeach (var s in services) if (serviceType.IsInstanceOfType(s)) candidates.Add(s);\nif (candidates.Count > 1) throw new InvalidOperationException(\"Ambiguous registrations: \" + serviceType.Name);","typeGuard":null,"tryCatchPattern":"try { svc = provider.TryGet(typeof(IMyService)); }\ncatch (InvalidOperationException ex) { log.Error(ex, \"Ambiguous service registrations\"); svc = null; }","preventionTips":["Register one instance per family of related types; query the most specific type","Avoid registering both a type and its base/interface separately","Keep the provider's parent chain free of overlapping registrations"],"tags":["dotnet","dependency-injection","ambiguous"],"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"}