/// <summary>
        /// Initializes a new instance of <see cref="DefaultTypeMappings{TRootType}"/>.
        /// </summary>
        /// <param name="assemblies">The assemblies that contain types that are assignable to the root type.</param>
        /// <param name="typeDescriptorPolicy">The type descriptor policy to use.</param>
        public DefaultTypeMappings(IEnumerable <Assembly> assemblies, TypeDescriptorPolicy typeDescriptorPolicy)
        {
            TypeDescriptorPolicy = typeDescriptorPolicy;
            var descriptorToType = new Dictionary <string, Type>();
            var typeToDescriptor = new Dictionary <Type, string>();
            var root             = typeof(TRootType);

            var types = assemblies.SelectMany(a => a.GetTypes().Where(root.IsAssignableFrom));

            foreach (var type in types)
            {
                var descriptor = typeDescriptorPolicy.GetTypeDescriptor(type);
                if (descriptor == null)
                {
                    if (type == RootType && typeDescriptorPolicy.FallbackToRootType)
                    {
                        continue;
                    }

                    throw new ArgumentException($"Type descriptor policy could not map type: {type}");
                }
                descriptorToType[descriptor] = type;
                typeToDescriptor[type]       = descriptor;
            }

            _descriptorToType = descriptorToType;
            _typeToDescriptor = typeToDescriptor;
        }
 /// <summary>
 /// Initializes a new instance of <see cref="ExtensibleJsonConverterFactory"/>.
 /// </summary>
 /// <param name="typeMappings">The type mappings.</param>
 /// <param name="defaultTypeDescriptor">The default type descriptor policy.</param>
 public ExtensibleJsonConverterFactory(IEnumerable <ITypeMappings> typeMappings, TypeDescriptorPolicy defaultTypeDescriptor)
 {
     _defaultTypeDescriptor = defaultTypeDescriptor;
     _allTypeMappings       = new ConcurrentDictionary <Type, ITypeMappings>();
     foreach (var typeMapping in typeMappings)
     {
         _allTypeMappings[typeMapping.RootType] = typeMapping;
     }
 }
Example #3
0
 public static IServiceCollection RegisterExtensibleTypes(
     this IServiceCollection serviceCollection,
     TypeDescriptorPolicy defaultTypeDescriptorPolicy = null,
     IDictionary <Type, TypeDescriptorPolicy> typeDescriptorPolicyOverrides = null)
 {
     return(serviceCollection.RegisterExtensibleTypes(defaultTypeDescriptorPolicy ?? TypeDescriptorPolicy.Default,
                                                      typeDescriptorPolicyOverrides ?? new Dictionary <Type, TypeDescriptorPolicy>(),
                                                      AppDomain.CurrentDomain.GetAssemblies()));
 }
Example #4
0
        public static IServiceCollection RegisterExtensibleTypes(
            this IServiceCollection serviceCollection,
            TypeDescriptorPolicy defaultTypeDescriptorPolicy,
            IDictionary <Type, TypeDescriptorPolicy> typeDescriptorPolicyOverrides,
            Assembly[] assemblies)
        {
            serviceCollection.Configure <JsonSerializerOptions>(options =>
            {
                var rootTypes = assemblies.SelectMany(a => a.GetTypes()
                                                      .Where(t =>
                {
                    if (!typeof(IExtensible).IsAssignableFrom(t))
                    {
                        return(false);
                    }

                    var extensionDataProperty = t.GetProperty(nameof(IExtensible.ExtensionData), typeof(ExtensionData));
                    return(extensionDataProperty != null && extensionDataProperty.DeclaringType == t);
                }))
                                .Distinct();

                var typeHierarchyAssemblyMapping = rootTypes.Select(t => new { Type = t, Assemblies = assemblies.Where(a => a.GetTypes().Any(t.IsAssignableFrom)).Distinct() })
                                                   .ToDictionary(o => o.Type, o => o.Assemblies);

                var typeMappings = new List <ITypeMappings>();

                foreach (var(type, relatedAssemblies) in typeHierarchyAssemblyMapping)
                {
                    if (!typeDescriptorPolicyOverrides.TryGetValue(type, out var typeDescriptorPolicy))
                    {
                        typeDescriptorPolicy = defaultTypeDescriptorPolicy;
                    }
                    typeMappings.Add(SerializationHelpers.CreateConstructor <SerializationHelpers.DefaultTypeMappingsConstructorDelegate>(typeof(DefaultTypeMappings <>).MakeGenericType(type))(relatedAssemblies, typeDescriptorPolicy));
                }

                options.Converters.Add(new ExtensibleJsonConverterFactory(typeMappings, defaultTypeDescriptorPolicy));
            });

            return(serviceCollection);
        }