Home > Software design >  Class behavior based on given data
Class behavior based on given data

Time:05-24

I am receiving an IFormFile from a controller. What I want to do next is to process it and get its content. I expect to get .docx, .txt or .pdf file and I want a single class to process any of these files based on extension given. I created and made my class to do it like that:

{
    public static class DocumentProcessor // Should it be like this?
    {
        public static string GetContent(IFormFile file)
        {
            var result = new StringBuilder();

            switch (Path.GetExtension(file.FileName))
            {
                case ".txt":
                {
                    using(var reader = new StreamReader(file.OpenReadStream()))
                    {
                        while (reader.Peek() >= 0)
                            result.AppendLine(reader.ReadLine());
                    }
                    break;
                }
            }
            return result.ToString();
        }
    }
}

Anyway, I feel like it is an extremely bad solution just because it is static. I could use the strategy pattern, but how do I define what strategy context has to use? Should I create another class that returns a Strategy object depending on IFormFile object extension. But I feel it is also a bad solution I would like to know what is the best way to solve this problem

CodePudding user response:

Create a new interface

interface IDocumentParser {
    string GetContent(IFormFile file);
}

Implement that interface once per parser extension, e.g.:

class TextFileParser : IDocumentParser {
    public string GetContent(IFormFile file) {
        //your implementation code here
    }
}

Then implement a factory:

class ParserFactory {
    public static IDocumentParser GetParserForFilename(string filename) {
        /*
           This is the simple way. A more complex yet elegant way would be for all parsers to include a property exposing the filetypes it supports, and they are loaded through reflection or dependency injection.
        */
        switch (Path.GetExtension(fileName))
            {
                case ".txt":
                {
                    return new TextFileParser();
                }
                // add additional parsers here
            }
            return null;
    }
}

And use:

IDocumentParser parser = ParserFactory.GetParserForFilename(file.FileName);
string content = parser.GetContent(file);

This is known as "Inversion of Control".

  • Related