/// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }