/// <summary> /// Add an alternative mapping destination type, and provide the opportunity to customize that. /// </summary> /// <typeparam name="TNewDestType"></typeparam> /// <param name="defaultIncludes"></param> /// <param name="config"></param> /// <returns></returns> public ProjectionDefinitionConfiguration <TSourceType, TNewDestType> AlternativeMap <TNewDestType>( string defaultIncludes = null, Action <ProjectionDefinitionConfiguration <TSourceType, TNewDestType> > config = null) { var parsedDefaultIncludes = (defaultIncludes == null) ? new List <PropertyReference> { } : (List <PropertyReference>)PropertyReference.Parse(defaultIncludes); defaultIncludes = PropertyReference.CompareAndConstructDefaultIncludes(parsedDefaultIncludes, typeof(TNewDestType).GetTypeInfo()); var newMapping = new ProjectionDefinitionConfiguration <TSourceType, TNewDestType> { InternalMappingDefinition = InternalMappingDefinition, InternalProjectionDefinition = new ProjectionDefinition { DefaultIncludes = defaultIncludes, DestinationType = typeof(TNewDestType), } }; InternalMappingDefinition.Destinations.Add(typeof(TNewDestType), newMapping.InternalProjectionDefinition); if (config != null) { config(newMapping); } return(newMapping); }
/// <summary> /// Add a mapping of a data type to a projection type /// </summary> /// <typeparam name="TSourceType"></typeparam> /// <typeparam name="TDestType"></typeparam> /// <param name="defaultIncludes"></param> /// <param name="config"></param> /// <returns></returns> public PopcornConfiguration Map <TSourceType, TDestType>( string defaultIncludes = null, Action <MappingDefinitionConfiguration <TSourceType, TDestType> > config = null) { var sourceType = typeof(TSourceType); var destType = typeof(TDestType); // Validate and construct the actual default includes from both attributes and those passed in at the time of the mapping var destTypeInfo = typeof(TDestType).GetTypeInfo(); var parsedDefaultIncludes = (defaultIncludes == null) ? new List <PropertyReference> { } : (List <PropertyReference>)PropertyReference.Parse(defaultIncludes); defaultIncludes = PropertyReference.CompareAndConstructDefaultIncludes(parsedDefaultIncludes, destTypeInfo); var mappingConfiguration = new MappingDefinitionConfiguration <TSourceType, TDestType> { }; // Assign the existing mapping to be configured should it already exist if (_expander.Mappings.ContainsKey(sourceType)) { // We will allow a client to reference the same mapping multiple times to add more translations etc, // but ONLY if the types remain consistent! if (_expander.Mappings[sourceType].DefaultDestinationType != destType) { throw new InvalidOperationException($"Expander was default-mapped multiple times for {sourceType}."); } // Assign the existing mapping information mappingConfiguration.InternalMappingDefinition = _expander.Mappings[sourceType]; mappingConfiguration.InternalProjectionDefinition = _expander.Mappings[sourceType].Destinations[destType]; } else { // Create the configuration starting with the 'default' mapping mappingConfiguration.InternalMappingDefinition = new MappingDefinition { DefaultDestinationType = destType, }; // And assign it a projecion definition mappingConfiguration.InternalProjectionDefinition = new ProjectionDefinition { DefaultIncludes = defaultIncludes, DestinationType = destType, }; mappingConfiguration.InternalMappingDefinition.Destinations.Add(destType, mappingConfiguration.InternalProjectionDefinition); _expander.Mappings.Add(typeof(TSourceType), mappingConfiguration.InternalMappingDefinition); } if (config != null) { config(mappingConfiguration); } return(this); }