Пример #1
0
        /// <summary>
        /// Processes <paramref name="rawAddressData"/> with the RegEx set up in <typeparamref name="TOutputFormat"/>.
        /// </summary>
        /// <remarks>The input and output manipulation functions will also be processed.</remarks>
        /// <param name="rawAddressData">The input string.</param>
        /// <exception cref="ArgumentNullException"><see cref="IOutputFormat.MatchingRegex"/> must be set up correctly in the generic class.</exception>
        /// <exception cref="MissingMemberException">Should contain at least one <see cref="RegexGroupAttribute"/>.</exception>
        /// <example>
        /// This sample shows how to call the <see cref="AddressSeparationProcessor{TOutputFormat}"/> constructor.
        /// <code>
        /// class TestClass
        /// {
        ///     static int Main()
        ///     {
        ///         var processor = new AddressSeparationProcessor{GermanSimpleOutputFormat}();
        ///         var result = processor.Process('Teststraße 123a');
        ///         var address = result.ResolvedAddress;
        ///
        ///         Console.WriteLine($"Name is {address.StreetName} with number {address.HouseNumber} and affix {address.HouseNumberAffix}");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <returns>The resolved address along with info about the processing.</returns>
        public OutputResult <TOutputFormat> Process(string rawAddressData)
        {
            // sanity check
            var outputFormatInstance = Activator.CreateInstance(typeof(TOutputFormat)) as IOutputFormat;

            _       = outputFormatInstance.MatchingRegex ?? throw new ArgumentNullException(nameof(outputFormatInstance.MatchingRegex));
            Options = Options ?? new DefaultProcessingOptions();

            // create output instance
            var outputResult = new OutputResult <TOutputFormat>(rawAddressData);

            // return empty result, if input is empty
            if (String.IsNullOrWhiteSpace(rawAddressData))
            {
                return(outputResult);
            }

            // call user defined input functions
            rawAddressData = this.ProcessInputManipulationQueue(rawAddressData);

            // get all properties w/ RegexGroupAttribute and throw exception if there is none
            var propertyRegexGroupCollection = OutputFormatHelper.GetPropertyRegexGroups(typeof(TOutputFormat));

            if (Options.ThrowIfNoRegexGroupPropertyProvided &&
                propertyRegexGroupCollection.Any() == false)
            {
                throw new MissingMemberException($"Class {typeof(TOutputFormat).Name} has no property members with {nameof(RegexGroupAttribute)}.");
            }

            // assign to Regex bindings
            var match = outputFormatInstance.MatchingRegex.Match(rawAddressData);

            if (match.Success)
            {
                foreach (var prop in propertyRegexGroupCollection)
                {
                    // get first matching group value; null, if no group is matching
                    string valueOfGroup = null;
                    do
                    {
                        // get groups one by one and manipulate if necessary
                        var currentGroup = prop.RegexGroupCollection.Dequeue();
                        valueOfGroup = match.Groups[currentGroup.RegexGroupIndex]?.Value;
                        valueOfGroup = this.ProcessOutputManipulation(valueOfGroup, currentGroup);

                        // set value to instance member
                        this.SetPropertyValue(prop.Property, outputResult.GetInstance(), valueOfGroup);
                    } while (prop.RegexGroupCollection.Count > 0 && String.IsNullOrWhiteSpace(valueOfGroup));
                }

                // set success
                outputResult.AddressHasBeenResolved = true;
            }

            // return filled instance
            return(outputResult);
        }