public Pipeline <MappingTableParseInput, MappingTableParseModel, Workbook, IReadOnlyDictionary <IParseAddress, TContract> > Create <TContract>(ExcelRecordMapping mapping)
            where TContract : new()
        {
            var rowPipeline = AsposePipelineExtensions.StartPipeline <MappingTableParseInput, MappingTableParseModel, Row>()
                              .WithModel(() => new TContract())
                              .Aggregate(mapping.Properties, PipeContractProperty)
                              .ExtractModel();

            return(AsposePipelineExtensions.StartPipeline <MappingTableParseInput, MappingTableParseModel, Workbook>()
                   .Worksheet(mapping.WorksheetName)
                   .Rows(mapping.StartRow)
                   .Transform(rowPipeline.Run));
        }
        private Pipeline <MappingTableParseInput, MappingTableParseModel, Row, RowWithModel <TContract> > PipeContractProperty <TContract>(
            Pipeline <MappingTableParseInput, MappingTableParseModel, Row, RowWithModel <TContract> > previous,
            ExcelRecordMappingProperty property)
            where TContract : new()
        {
            var propertySetter = _propertySetterProvider.For(typeof(TContract), property.PropertyPath);

            var propertyCellPipeline    = AsposePipelineExtensions.StartPipeline <MappingTableParseInput, MappingTableParseModel, Row>().Cell(property.ColumnName);
            var propertyValuePipeline   = _extractPrimitivePipelineSetupHelper.For(propertyCellPipeline, propertySetter.RequiredType);
            var propertyAddressPipeline = propertyCellPipeline.Address();

            return(previous.SetProperty(
                       propertySetter,
                       (x, y, z) => z.Model,
                       (x, y, z) => new ValueWithAddress <object>
            {
                Address = propertyAddressPipeline.Run(x, y, z.Row),
                Value = propertyValuePipeline.Run(x, y, z.Row)
            }));
        }