3
\$\begingroup\$

I have a controller in an ASP.NET Web API application which generates a CSV file. The controller looks like this:

[System.Web.Http.HttpGet]
public HttpResponseMessage Download(int? id = null)
{
    if ( !id.HasValue)
        return new HttpResponseMessage(HttpStatusCode.NotFound);

    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new StreamContent(new MemoryStream(_personService
        .ExportPersonsToCSV().Content));
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
    result.Content.Headers.ContentDisposition = new 
        ContentDispositionHeaderValue("attachment") {  
            FileName = _personService.ExportPersonsToCSV().FileName };
    return result;
}

And method ExportPersonsToCSV() of PersonService class:

public FileDTO ExportPersonsToCSV()
{
    //...
    var dto = new FileDTO()
    {
        FileName = $"Persons {DateTime.Now}.csv",
        MediaTypeHeaderValue = Globals.MEDIA_TYPE_HEADER_VALUE,
        Content = _csvExport.WriteCSV(personDeps, columnNames)
    };
    return dto;
}

And CSVExport class looks like this:

public class CSVExport : ICSVExport
{
    /// <summary>
    /// Converting content of MemoryStream into byte array
    /// </summary>        
    public byte[] WriteCSV<T>(IEnumerable<T> objectlist
        , IEnumerable<string> columnNames = null)
    {
        byte[] bytes = null;
        using (var memStream = new MemoryStream())
        using (var sw = new StreamWriter(memStream, Encoding.GetEncoding("Windows-1251")))
        {
            sw.WriteLine("sep=,");
            foreach (var line in ToCsv(objectlist, columnNames))
            {
                sw.WriteLine(line);
            }
            sw.Flush();
            memStream.Seek(0, SeekOrigin.Begin);
            bytes = memStream.ToArray();
        }
        return bytes;
    }

    private IEnumerable<string> ToCsv<T>(IEnumerable<T> objectlist, 
         IEnumerable<string> columnNames = null, string separator = ",", 
         bool header = true)
    {
        //... code omitted for the brevity
        yield return string.Join(separator, fields                        
                    .ToArray());                
    }
}

Recently, I've thought whether a method public byte[] WriteCSV<T>(...) is a violation of Single Responsibility Principle?

My thought it is ok to place here:

  • It is appropriate place to put a logic of converting csv file into byte array cause a method public byte[] WriteCSV<T>(...) placed into a class CSVExport

My thoughts it is NOT ok to place here:

  • What is MemoryStream class doing here? It is a class of ExportCSV and nothing more!
  • It is possible to extract dependency(MemoryStream) into separate class like and use it into CSVExport: IMemoryStream{ byte[] WriteCSV(IEnumerable objects);}

So is a method public byte[] WriteCSV<T>(...) placed into CSVExport a violation of Single Responsibility Principle? Any other criticism are welcome.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Just curious, did you consider using a csv library such as CsvHelper ? \$\endgroup\$ Commented Apr 2, 2019 at 20:34
  • \$\begingroup\$ @BradM Thanks for advice, however, I would like to implement by myself:) \$\endgroup\$ Commented Apr 3, 2019 at 7:12

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.