Skip to main content
Code Review

Return to Question

added 51 characters in body
Source Link
Dmitry Nogin
  • 6.1k
  • 3
  • 21
  • 40
public class NameFile : RowFile<NameFile, FullName>
{
 protected override IEnumerable<FullName> Read(RowReader reader)
 {
 using(reader)
 while (reader.Read())
 yield return new FullName
 {
 First = reader.Get<string>("First"),
 Last = reader.Get<string>("Last")
 };
 }
}
public class NameFile : RowFile<NameFile, FullName>
{
 protected override IEnumerable<FullName> Read(RowReader reader)
 {
 while (reader.Read())
 yield return new FullName
 {
 First = reader.Get<string>("First"),
 Last = reader.Get<string>("Last")
 };
 }
}
public class NameFile : RowFile<NameFile, FullName>
{
 protected override IEnumerable<FullName> Read(RowReader reader)
 {
 using(reader)
 while (reader.Read())
 yield return new FullName
 {
 First = reader.Get<string>("First"),
 Last = reader.Get<string>("Last")
 };
 }
}
edited body
Source Link
Dmitry Nogin
  • 6.1k
  • 3
  • 21
  • 40

Using library class FowFile<TFileRowFile<TFile, TRow>:

Using library class FowFile<TFile, TRow>:

Using library class RowFile<TFile, TRow>:

Source Link
Dmitry Nogin
  • 6.1k
  • 3
  • 21
  • 40

Inverting 3rd party dependency

Looking for a way to efficiently use 3rd party CSV reader without making a dependency on it. I would also prefer to make my class be available everywhere (not just in IoC container injectable Services), so I decided to go with a questionable decision – configure through the static property. Can you see a way to reduce amount of library code or make configuration more obvious without losing library handiness?

Repository at GitHub.

Project dependencies are:

enter image description here

And solution looks like this:

enter image description here

MyProject.Demo registers CSV library parser dependency and parses the CSV file:

class Program
{
 static void Main(string[] args)
 {
 CsvRowReader.Use();
 var text = "First,Last\nJohn,Doe\n";
 var file = NameFile.Parse(text);
 foreach (var name in file)
 WriteLine($"{name.First} {name.Last}");
 }
}

Business logic assembly MyProject defines NameFile as:

public class NameFile : RowFile<NameFile, FullName>
{
 protected override IEnumerable<FullName> Read(RowReader reader)
 {
 while (reader.Read())
 yield return new FullName
 {
 First = reader.Get<string>("First"),
 Last = reader.Get<string>("Last")
 };
 }
}

Where FullName is:

public class FullName
{
 public string First { get; set; }
 public string Last { get; set; }
}

Using library class FowFile<TFile, TRow>:

public abstract class RowFile<TFile, TRow> : Enumerable<TRow>
 where TFile : RowFile<TFile, TRow>, new()
{
 public static readonly TFile Empty = new TFile();
 public static TFile Parse(string text) =>
 Load(new StringReader(text));
 public static TFile Load(string filePath) =>
 Load(File.OpenText(filePath));
 public static TFile Load(Stream stream) =>
 Load(new StreamReader(stream));
 public static TFile Load(TextReader reader)
 {
 var file = new TFile();
 file.Rows = file.Read(RowReader.Create(reader));
 return file;
 }
 public sealed override IEnumerator<TRow> GetEnumerator() =>
 Rows.GetEnumerator();
 protected abstract IEnumerable<TRow> Read(RowReader read);
 IEnumerable<TRow> Rows { get; set; } = new TRow[0];
}

Where:

public abstract class RowReader : IDisposable
{
 public static Func<TextReader, RowReader> Create { get; protected set; }
 public abstract void Dispose();
 public abstract bool Read();
 public abstract T Get<T>(string name);
}

And:

public abstract class Enumerable<T> : IEnumerable<T>
{
 public abstract IEnumerator<T> GetEnumerator();
 IEnumerator IEnumerable.GetEnumerator() =>
 GetEnumerator();
}

3rd party CSV reader dependency is incapsulated in MyProject.CsvHelper project:

public class CsvRowReader : RowReader
{
 public static void Use() =>
 Create = reader => new CsvRowReader(reader);
 CsvRowReader(TextReader reader)
 {
 Reader = new CsvReader(reader);
 Reader.Read();
 Reader.ReadHeader();
 }
 CsvReader Reader { get; }
 public override void Dispose() =>
 Reader.Dispose();
 public override bool Read() =>
 Reader.Read();
 public override T Get<T>(string name) =>
 Reader.GetField<T>(name);
}

I don’t like all those mutability things, but do not see a better solution at the moment...

lang-cs

AltStyle によって変換されたページ (->オリジナル) /