{"record":{"id":"5308bedad18245f5","repo":"PrismLibrary/Prism","slug":"mapping-with-the-given-type-is-already-registered-0","errorCode":null,"errorMessage":"Mapping with the given type is already registered: {0}.","messagePattern":"Mapping with the given type is already registered: (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Navigation/Regions/Adapters/RegionAdapterMappings.cs","lineNumber":25,"sourceCode":"/// <summary>\n/// This class maps <see cref=\"Type\"/> with <see cref=\"IRegionAdapter\"/>.\n/// </summary>\npublic class RegionAdapterMappings\n{\n    private readonly Dictionary<Type, IRegionAdapter> mappings = [];\n\n    /// <summary>\n    /// Registers the mapping between a type and an adapter.\n    /// </summary>\n    /// <typeparam name=\"TControl\">The type of the control</typeparam>\n    /// <typeparam name=\"TAdapter\">The type of the IRegionAdapter to use with the TControl</typeparam>\n    /// <exception cref=\"InvalidOperationException\">Throws <see cref=\"InvalidOperationException\"/> when a mapping has already been defined for a specified control type.</exception>\n    public void RegisterMapping<TControl, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TAdapter>() where TAdapter : IRegionAdapter\n    {\n        var controlType = typeof(TControl);\n\n        if (mappings.ContainsKey(controlType))\n            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,\n                                                              Resources.MappingExistsException, controlType.Name));\n\n        var adapter = ContainerLocator.Container.Resolve<TAdapter>();\n\n        mappings.Add(controlType, adapter);\n    }\n\n    /// <summary>\n    /// Removes an existing Registration if one exists and registers the new mapping between a type and an adapter.\n    /// </summary>\n    /// <typeparam name=\"TControl\">The type of the control</typeparam>\n    /// <typeparam name=\"TAdapter\">The type of the IRegionAdapter to use with the TControl</typeparam>\n    public void RegisterOrReplaceMapping<TControl, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TAdapter>() where TAdapter : IRegionAdapter\n    {\n        var controlType = typeof(TControl);\n        var adapter = ContainerLocator.Container.Resolve<TAdapter>();\n\n        if (mappings.ContainsKey(controlType))","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Navigation/Regions/Adapters/RegionAdapterMappings.cs#L7-L43","documentation":"RegionAdapterMappings.RegisterMapping throws InvalidOperationException (Resources.MappingExistsException) when a mapping for the given control type already exists. The dictionary enforces one adapter per control type to make region adapter resolution deterministic.","triggerScenarios":"Calling RegisterMapping<TControl, TAdapter> twice for the same TControl — most commonly by overriding ConfigureRegionAdapterMappings in a PrismApp-derived class and re-registering a default adapter that Prism already registered internally, or calling the override both in base and derived bootstrapper code.","commonSituations":"Customizing region adapters in a Prism.Maui app while the base registration already added the default adapter (e.g. re-registering ContentPresenter/ScrollView adapters); duplicate startup code paths running ConfigureRegionAdapterMappings twice.","solutions":["Only register mappings for control types that do not yet have a mapping (the built-in ones are pre-registered)","Remove duplicate RegisterMapping calls for control types already mapped by Prism defaults","If replacement is truly required, add a non-throwing path: check/replace the mapping via the underlying dictionary or clear it before registering (may require a custom mappings subclass)","Guard the call by checking whether the type is already mapped before registering"],"exampleFix":"// before\nprotected override void ConfigureRegionAdapterMappings(IRegionAdapterMappings mappings)\n{\n    base.ConfigureRegionAdapterMappings(mappings);\n    mappings.RegisterMapping<ScrollView, MyScrollViewAdapter>(); // already registered\n}\n\n// after\nprotected override void ConfigureRegionAdapterMappings(IRegionAdapterMappings mappings)\n{\n    base.ConfigureRegionAdapterMappings(mappings);\n    mappings.RegisterMapping<MyCustomControl, MyCustomControlAdapter>(); // new type only\n}","handlingStrategy":"try-catch","validationCode":"// RegisterMapping does not expose a TryGetValue; only register custom control types\nbool isNewType = myControlType != typeof(ScrollView) && myControlType != typeof(ContentPresenter);","typeGuard":null,"tryCatchPattern":"try { mappings.RegisterMapping<MyControl, MyControlAdapter>(); }\ncatch (InvalidOperationException) { /* mapping already exists — skip or replace via custom mappings */ }","preventionTips":["Only call RegisterMapping for your own custom control types","Remember Prism pre-registers default adapters in ConfigureRegionAdapterMappings","Call base.ConfigureRegionAdapterMappings once; avoid duplicated startup paths"],"tags":["prism","maui","regions","duplicate-registration"],"backgroundTag":"file-already-exists","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}