File: FormMapping\Factories\Collections\ConcreteTypeCollectionConverterFactory.cs
Web Access
Project: src\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.Diagnostics.CodeAnalysis;
 
namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping;
 
internal class ConcreteTypeCollectionConverterFactory<TCollection, TElement>
    : IFormDataConverterFactory
{
    public static readonly ConcreteTypeCollectionConverterFactory<TCollection, TElement> Instance =
        new();
 
    [UnconditionalSuppressMessage("Trimming", "IL2046", Justification = "This derived implementation doesn't require unreferenced code like other implementations of the interface.")]
    [UnconditionalSuppressMessage("AOT", "IL3051", Justification = "This derived implementation doesn't use dynamic code like other implementations of the interface.")]
    public bool CanConvert(Type _, FormDataMapperOptions options) => true;
 
    [RequiresDynamicCode(FormMappingHelpers.RequiresDynamicCodeMessage)]
    [RequiresUnreferencedCode(FormMappingHelpers.RequiresUnreferencedCodeMessage)]
    public FormDataConverter CreateConverter(Type _, FormDataMapperOptions options)
    {
        // Resolve the element type converter
        var elementTypeConverter = options.ResolveConverter<TElement>() ??
            throw new InvalidOperationException($"Unable to create converter for '{typeof(TCollection).FullName}'.");
 
        var customFactory = Activator.CreateInstance(typeof(CustomCollectionConverterFactory<>)
            .MakeGenericType(typeof(TCollection), typeof(TElement), typeof(TCollection))) as CustomCollectionConverterFactory;
 
        if (customFactory == null)
        {
            throw new InvalidOperationException($"Unable to create converter for type '{typeof(TCollection).FullName}'.");
        }
 
        return customFactory.CreateConverter(elementTypeConverter);
    }
 
    private abstract class CustomCollectionConverterFactory
    {
        public abstract FormDataConverter CreateConverter(FormDataConverter<TElement> elementConverter);
    }
 
    private class CustomCollectionConverterFactory<TCustomCollection> : CustomCollectionConverterFactory
        where TCustomCollection : TCollection, ICollection<TElement>, new()
    {
        public override FormDataConverter CreateConverter(FormDataConverter<TElement> elementConverter)
        {
            return new CollectionConverter<
            TCustomCollection,
            ImplementingCollectionBufferAdapter<TCustomCollection, TCustomCollection, TElement>,
            TCustomCollection,
            TElement>(elementConverter);
        }
    }
}