Hello @Dani_S ,
I appreciate the effort you’ve put into this, but there are a few areas that could cause problems down the road.
In summary, what I'd recommend
These are architectural decisions you'll need to work through on your end since you know your requirements best.
- Consolidate the converters into one that handles format detection and routing.
- Refactor the large
Convertmethod into smaller focused methods. - Replace switch statements with dictionaries. Separate validation from directory creation.
- Move license initialization to startup. Strengthen tests to validate output contents, not just file existence.
For more details, see below.
The biggest issue: creating 14 separate converter classes
I made converter to each format is it ok?
That means you're writing essentially the same code 14 times, right?
All your converters follow the same steps. The only difference is which driver you’re using, and you already have a helper that maps format names to drivers.
A single converter using those helpers would let you maintain one codebase, fix bugs once, and add features once.
The ShapefileConverter method does too much
Can you please check the code and see if there are problem, or need refactor?
Your Convert method is handling too many responsibilities in one place, which makes it hard to follow and test.
Breaking it into smaller methods where each has one job—one validates archive contents, another extracts, another converts—would make the code easier to read, test, and debug.
Switch statements instead of dictionaries
Your FileExtensionHelpers class uses switch statements with 15+ cases. The runtime checks each case until it finds a match. Dictionaries do direct lookups, which are faster and cleaner. Adding new formats with a switch means modifying code, while with dictionaries it’s just one line of initialization.
Something like this would be more efficient:
public static class FileExtensionHelpers
{
private static readonly Dictionary<FileExtension, string> ExtensionMap = new()
{
{ FileExtension.Csv, ". csv" },
{ FileExtension.EsriJson, ".json" },
{ FileExtension.FileGdb, ".gdbtable" },
{ FileExtension.GeoJson, ".json" },
{ FileExtension.GeoJsonSeq, ". json" },
{ FileExtension.GeoPackage, ".gpkg" },
{ FileExtension. Gml, ".gml" },
{ FileExtension.Gpx, ".gpx" },
{ FileExtension.Kml, ".kml" },
{ FileExtension.Kmz, ".kml" },
{ FileExtension.MapInfoInterchange, ".mid" },
{ FileExtension.MapInfoTab, ".tab" },
{ FileExtension. OsmXml, ".osm" },
{ FileExtension.Shapefile, ".shp" },
{ FileExtension.TopoJson, ".json" }
};
private static readonly Dictionary<string, FileExtension> OptionMap = new(StringComparer.OrdinalIgnoreCase)
{
{ "geojson", FileExtension.GeoJson },
{ "geojsonseq", FileExtension.GeoJsonSeq },
{ "esrijson", FileExtension.EsriJson },
{ "gdb", FileExtension.FileGdb },
{ "filegdb", FileExtension.FileGdb },
{ "kml", FileExtension.Kml },
{ "kmz", FileExtension.Kmz },
{ "shapefile", FileExtension.Shapefile },
{ "topojson", FileExtension.TopoJson },
{ "osm", FileExtension.OsmXml },
{ "osmxml", FileExtension.OsmXml },
{ "gpx", FileExtension.Gpx },
{ "gml", FileExtension.Gml },
{ "mif", FileExtension.MapInfoInterchange },
{ "mapinfointerchange", FileExtension.MapInfoInterchange },
{ "tab", FileExtension.MapInfoTab },
{ "mapinfotab", FileExtension.MapInfoTab },
{ "csv", FileExtension.Csv },
{ "gpkg", FileExtension.GeoPackage },
{ "geopackage", FileExtension. GeoPackage }
};
// O(1) lookup instead of O(n) switch
public static string ToDotExtension(this FileExtension ext) =>
ExtensionMap.TryGetValue(ext, out var result) ? result : string.Empty;
public static FileExtension? FromOption(string option) =>
string.IsNullOrWhiteSpace(option) ? null :
OptionMap.TryGetValue(option. Trim(), out var result) ? result : (FileExtension?)null;
}
Mixing validation with side effects
Your ValidateAndPreparePaths method both checks validity and creates directories. Validation should only report problems, while preparation should create resources. Keeping these separate means you can validate without creating anything, and test validation without touching the file system.
Applying license on every conversion
I added ShapefileConverter and all its helper classes + tests(ShapefileConverterIntegrationTests.txt)??
You call AsposeLicenseManager.ApplyLicense in every conversion. The license doesn’t change between conversions.
Apply it once at application startup, then every conversion will use the licensed library automatically.
Tests don’t verify enough
Your integration test checks if files exist, but not whether the conversion worked correctly. Did geometry get preserved? Are attributes intact? Is the output format correct? Stronger tests would load the output and verify that contents match expectations. They’d also test malformed archives, missing files, and invalid options.