/// <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; } }
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())); }
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); }