2

I'm studying D.I. I've some issues with the architecture, maybe I'm missing some points.

Suppose I have this non-DI code (I read a list of "Person" from file)

static void Main()
{
 PersonReaderFromFile personReader = new PersonReaderFromFile("path-to-file");
 Person p = personReader.GetNext(); //return a Person parsed from file line or NULL at EOF
}
class Person 
{
 //stuffs here
}
class PersonReaderFromFile
{
 public Person GetNext()
 {
 Person person = new Person();
 //some logic
 return person;
 }
}

First, for implementing D.I. patterns, I need interfaces, so I do

static void Main()
{
 iPersonReader personReader = new PersonReaderFromFile("path-to-file");
 iPerson p = personReader.GetNext();
}
interface iPerson
{
}
class Person : iPerson
{
}
interface iPersonReader
{
 iPerson GetNext();
}
class PersonReaderFromFile : iPersonReader
{
 public iPerson GetNext()
 {
 Person person = new Person();
 //some logic
 return person;
 }
}

And now my issue: PersonReaderFromFile depends on Person implementation. It's ok? Or I need an extra class, like a PersonFactory?

static void Main()
{
 iPersonFactory factory = new PersonFactory();
 iPersonReader personReader = new PersonReaderFromFile("path-to-file", factory);
 iPerson person = personReader.GetNext();
}
interface iPerson
{
}
class Person : iPerson
{
}
interface iPersonReader
{
 iPerson GetNext();
}
class PersonReaderFromFile : iPersonReader
{
 iPersonFactory _factory;
 public PersonReaderFromFile(iPersonFactory factory)
 {
 _factory = factory;
 }
 public iPerson GetNext()
 {
 Person person = _factory.CreateNewPerson();
 //some logic
 return person;
 }
}
interface iPersonFactory 
{
 iPerson CreateNewPerson();
}
class PersonFactory : iPersonFactory
{
 iPerson CreateNewPerson()
 {
 Person person = new Person();
 return person;
 }
}

Now PersonFactory depends on Person implementation, but it should be correct. Any advice? Tnx to all.

EDIT: I show a sample PersonReaderFromFile implementation

class PersonReaderFromFile
{
 StreamReader _fileReader;
 public PersonReaderFromFile(string path)
 {
 _fileReader = new StreamReader(file);
 }
 public Person GetNext()
 {
 string line = _fileReader.ReadLine();
 if (line == null)
 {
 _fileReader.Close();
 return null;
 }
 string name, lastName, email;
 ParseInformationFromLine(line, out name, out lastName, out email);
 Person p = new Person { Name = name, LastName = lastName, Email = email };
 return p;
 }
 private ParseInformationFromLine(string line, out string name, out string lastName, out string email)
 {
 //I don't think that matters
 }
}
asked Mar 30, 2020 at 14:49

1 Answer 1

1

PersonReaderFromFile does not depend on Person. That class appears to be just a POCO that represents run time data.

PersonReaderFromFile is dependent on StreamReader along with ParseInformationFromLine function

First abstract out those implementation details into their own concerns.

public interface IReadLines {
 string ReadLine();
}
public interface IParsePersonInformationFromLine {
 void ParseInformationFromLine(string line, out string name, out string lastName, out string email);
}

The target class would explicitly depend on the abstractions

public class PersonReaderFromFile {
 private readonly IReadLines reader;
 private readonly IParsePersonInformationFromLine parser;
 public PersonReaderFromFile(IReadLines reader, IParsePersonInformationFromLine parser) {
 this.reader = reader;
 this.parser = parser;
 }
 public Person GetNext() {
 string line = reader.ReadLine();
 if (line == null) {
 return null;
 }
 string name, lastName, email;
 parser.ParseInformationFromLine(line, out name, out lastName, out email);
 Person p = new Person { Name = name, LastName = lastName, Email = email };
 return p;
 }
}

The individual abstractions would have their own implementations to satisfy the desired functionality that would be used at run time. For example the reader would internally still use a StreamReader to get the lines. PersonReaderFromFile does not need to know anything about how the line is retrieved. Just that it wants a line when called.

Main now can be refactored to use Pure DI for example

static void Main() {
 IReadLines reader = new ReadLinesImplementation("path-to-file");
 IParsePersonInformationFromLine parser = new ParsePersonInformationFromLine(); 
 PersonReaderFromFile personReader = new PersonReaderFromFile(reader, parser);
 Person p = personReader.GetNext(); //return a Person parsed from file line or NULL at EOF
}

There are further refactors that can be applied but this is only meant to be a simplified example of the identifying implementation details that should be abstracted out of code that is tightly coupled to implementation concerns.

answered Mar 30, 2020 at 15:46
Sign up to request clarification or add additional context in comments.

1 Comment

Great! Thanks so much for your time! If you want, could you also show me the other refactoring you were talking about? (if you have time, I don't want to bother)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.