{"record":{"id":"3c45ef94d43b41af","repo":"OrchardCMS/OrchardCore","slug":"could-not-resolve-extension-for-type-dependency-name","errorCode":null,"errorMessage":"Could not resolve extension for type {dependency.Name}.","messagePattern":"Could not resolve extension for type (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore/Extensions/Features/TypeFeatureProvider.cs","lineNumber":17,"sourceCode":"using System.Collections.Concurrent;\nusing OrchardCore.Environment.Extensions.Features;\n\nnamespace OrchardCore.Environment.Extensions;\n\npublic class TypeFeatureProvider : ITypeFeatureProvider\n{\n    private readonly ConcurrentDictionary<Type, IEnumerable<IFeatureInfo>> _features = new();\n\n    public IExtensionInfo GetExtensionForDependency(Type dependency)\n    {\n        if (_features.TryGetValue(dependency, out var features))\n        {\n            return features.First().Extension;\n        }\n\n        throw new InvalidOperationException($\"Could not resolve extension for type {dependency.Name}.\");\n    }\n\n    public IFeatureInfo GetFeatureForDependency(Type dependency)\n    {\n        if (_features.TryGetValue(dependency, out var features))\n        {\n            // Gets the first feature that has the same ID as the extension, if any. \n            // Otherwise returns the first feature.\n            return features.FirstOrDefault(feature => feature.Extension.Id == feature.Id) ?? features.First();\n        }\n\n        throw new InvalidOperationException($\"Could not resolve main feature for type {dependency.Name}.\");\n    }\n\n    public IEnumerable<IFeatureInfo> GetFeaturesForDependency(Type dependency)\n    {\n        if (_features.TryGetValue(dependency, out var features))\n        {","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore/Extensions/Features/TypeFeatureProvider.cs#L1-L35","documentation":"TypeFeatureProvider maintains a map from DI service types to the features that registered them. GetExtensionForDependency looks up the dependency type in this map and returns the extension (module) of the first associated feature. If the type was never registered through TryAdd, no extension can be resolved and this InvalidOperationException is thrown.","triggerScenarios":"Calling GetExtensionForDependency(type) with a Type that was never passed to TryAdd — i.e., a type whose service was not registered by any module's Startup class tracked by the feature provider.","commonSituations":"Resolving extension info for a framework/abstraction service type that lives outside any module; calling during early startup before feature type discovery has run; service registered manually in DI outside a module startup.","solutions":["Verify the type is registered by a module's Startup class that participates in feature type discovery.","Ensure the call happens after the shell's feature/DI map is fully built.","Use TryGetValue-style defensive checks on the underlying map or guard with _features.ContainsKey before calling.","If the type legitimately has no module, handle it separately instead of routing it through TypeFeatureProvider."],"exampleFix":"// before\nvar extension = typeFeatureProvider.GetExtensionForDependency(typeof(SomeService));\n\n// after\nif (typeFeatureProvider.GetFeaturesForDependency(typeof(SomeService)) is { } features) { /* use features.First().Extension */ }\n// or ensure SomeService is registered from a module Startup class","handlingStrategy":"type-guard","validationCode":"bool canResolve = typeFeatureProvider.GetFeaturesForDependency(dependency) is not null;","typeGuard":"bool IsKnownDependency(Type dependency) =>\n    typeFeatureProvider.GetFeaturesForDependencySafe(dependency) is { Count: > 0 }; // or wrap lookup in try/catch and expose TryGet","tryCatchPattern":"try { var ext = provider.GetExtensionForDependency(type); }\ncatch (InvalidOperationException) { ext = null; /* type lives outside any module */ }","preventionTips":["Register services only from module Startup classes participating in feature discovery.","Resolve extensions only for types that came from the shell's DI container.","Call after shell composition completes, never during early host startup."],"tags":["dependency-injection","modules","features"],"backgroundTag":"resource-not-found","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}