| File: FormMapping\FormDataMapperOptions.cs | Web Access |
| Project: src\aspnetcore\src\Components\Endpoints\src\Microsoft.AspNetCore.Components.Endpoints.csproj (Microsoft.AspNetCore.Components.Endpoints) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping; internal sealed class FormDataMapperOptions { private readonly ConcurrentDictionary<Type, FormDataConverter> _converters = new(); private readonly List<IFormDataConverterFactory> _factories = new(); [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] public FormDataMapperOptions() : this(NullLoggerFactory.Instance) { } [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] public FormDataMapperOptions(ILoggerFactory loggerFactory) { _converters = new(WellKnownConverters.Converters); _factories.Add(new ParsableConverterFactory()); _factories.Add(new FileConverterFactory()); _factories.Add(new EnumConverterFactory()); _factories.Add(new NullableConverterFactory()); _factories.Add(new DictionaryConverterFactory()); _factories.Add(new CollectionConverterFactory()); _factories.Add(new ComplexTypeConverterFactory(this, loggerFactory)); Logger = loggerFactory.CreateLogger<FormDataMapperOptions>(); } // For testing purposes only. internal List<IFormDataConverterFactory> Factories => _factories; internal ILogger Logger { get; } internal int MaxCollectionSize { get; set; } = FormReader.DefaultValueCountLimit; internal int MaxRecursionDepth { get; set; } = 64; internal int MaxErrorCount { get; set; } = 200; internal int MaxKeyBufferSize { get; set; } = FormReader.DefaultKeyLengthLimit; [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] internal FormDataConverter<T>? ResolveConverter<T>() { return (FormDataConverter<T>)_converters.GetOrAdd(typeof(T), CreateConverter, this); } [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] private static FormDataConverter CreateConverter(Type type, FormDataMapperOptions options) { foreach (var factory in options._factories) { if (factory.CanConvert(type, options)) { return factory.CreateConverter(type, options); } } throw new InvalidOperationException($"No converter registered for type '{type.FullName}'."); } [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] internal FormDataConverter ResolveConverter(Type type) { return _converters.GetOrAdd(type, CreateConverter, this); } // For testing [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] internal void AddConverter<T>(FormDataConverter<T> converter) { _converters[typeof(T)] = converter; } [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)] [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)] internal bool CanConvert(Type type) { if (_converters.ContainsKey(type)) { return true; } foreach (var factory in _factories) { if (factory.CanConvert(type, this)) { return true; } } return false; } }