I'm trying to build a fluent API for method chaining. These are the methods
public interface IBaseRelationships
{
IEnumerable<Person> Parents(IEnumerable<Person> people);
IEnumerable<Person> Children(IEnumerable<Person> people);
IEnumerable<Person> Siblings(IEnumerable<Person> people);
}
And the implementation
public class BaseRelationships : IBaseRelationships
{
public BaseRelationships(IFamilyGraph familyGraph)
{
FamilyGraph = familyGraph;
}
public IFamilyGraph FamilyGraph { get; }
public IEnumerable<Person> Parents(IEnumerable<Person> people)
{
List<Person> result = new List<Person>();
foreach (var person in people)
{
IPersonRelationships personRelationships = FamilyGraph.Get(person);
result.AddRange(personRelationships.Parents);
}
return result;
}
public IEnumerable<Person> Children(IEnumerable<Person> people)
{
List<Person> result = new List<Person>();
foreach (var person in people)
{
IPersonRelationships personRelationships = FamilyGraph.Get(person);
List<Person> children = personRelationships.Edges.Where(m => m.RelationshipType == RelationshipType.Parent)
.Select(m => m.Target)
.ToList();
result.AddRange(children);
}
return result;
}
public IEnumerable<Person> Siblings(IEnumerable<Person> people)
{
List<Person> result = new List<Person>();
return result;
}
}
}
I'd like to do something like this.
var person = new List<Person> {new Person()};
var cousins = person.Parents().Siblings().Children();
I know with this current implementation that is not possible and I might have to write extension methods. For that, the classes which contain the extension methods have to be static hence I can't inject the FamilyGraph
dependency.
With the current implementation if I return IBaseRelationships
instead of IEnumerable<Person>
I'll be able to get this to work. But I'm not sure how I'll be able to get the actual result (IEnumerable<Person>
) out of it.
Any idea on how to build this for the methods in the interface would be great.
Edit.
Addding FamilyGraph
fore reference
public class FamilyGraph : IFamilyGraph
{
private Dictionary<Person, PersonRelationships> Families;
public FamilyGraph(IPersonStore personStore)
{
Families = new Dictionary<Person, PersonRelationships>();
PersonStore = personStore;
}
public IPersonStore PersonStore { get; }
public void Add(EdgeInput inputEdge)
{
Edge edge;
try
{
edge = GetEdge(inputEdge);
}
catch (ArgumentException)
{
throw;
}
switch (edge.RelationshipType)
{
case Enums.RelationshipType.Parent:
AddParentRelationship(edge);
return;
case Enums.RelationshipType.Spouse:
AddSpouseRelationship(edge);
return;
}
}
public Edge GetEdge(EdgeInput inputEdge)
{
Person source, target;
try
{
source = PersonStore.GetPerson(inputEdge.Source);
target = PersonStore.GetPerson(inputEdge.Target);
}
catch (Exception)
{
throw;
}
return new Edge(source, target, inputEdge.RelationshipType);
}
public IPersonRelationships Get(Person person)
{
PersonRelationships personRelationships;
Families.TryGetValue(person, out personRelationships);
return personRelationships;
}
}
public interface IPersonRelationships
{
List<Edge> Edges { get; }
List<Person> Parents { get; }
Person Spouse { get; }
void AddEdge(Edge edge);
void AddParent(Person parent);
void AddSpouse(Person spouse);
bool CanAddParent(Person parent);
}
public interface IPersonStore
{
void Add(Person person);
bool Contains(string personName);
Person GetPerson(string personName);
}