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 classCSVExport
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.
CsvHelper
? \$\endgroup\$