在C#中建立流利的API或扩展方法以进行方法链接

时间:2019-06-15 13:31:31

标签: c# fluent method-chaining

我正在尝试构建用于方法链的流利的API。这些是方法

/etc/default/jetty

实施

public interface IBaseRelationships
{
    IEnumerable<Person> Parents(IEnumerable<Person> people);
    IEnumerable<Person> Children(IEnumerable<Person> people);
    IEnumerable<Person> Siblings(IEnumerable<Person> people);
}

我想做这样的事情。

   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;
        }
    }
}

我知道当前的实现是不可能的,我可能必须编写扩展方法。为此,包含扩展方法的类必须是静态的,因此我无法注入var person = new List<Person> {new Person()}; var cousins = person.Parents().Siblings().Children(); 依赖项。

在当前的实现中,如果我返回FamilyGraph而不是IBaseRelationships,则可以使它正常工作。但是我不确定如何从中获得实际结果(IEnumerable<Person>)。

关于如何为接口中的方法构建此方法的任何想法都会很棒。

编辑。 添加IEnumerable<Person>引用

FamilyGraph

1 个答案:

答案 0 :(得分:2)

让我们从您要公开的公共API的类型开始,我进行了一些小的调整以允许个人和集体。

var person = new Person();
var people = new List<Person> { person };
var cousins = person.Parents().Siblings().Children();
// Or
var cousins = people.Parents().Siblings().Children();

由于您要开始在一个人/多个人上链接,因此该人需要知道他们所属的FamilyGraph。

public class Person {

    public FamilyGraph FamilyGraph { get; set; }

    IEnumerable<Person> Parents() => FamilyGraph.Get(person).Parents;

    IEnumerable<Person> Children() => 
        FamilyGraph.Get(person).Edges
          .Where(m => m.RelationshipType == RelationshipType.Parent)
          .Select(m => m.Target)
          .ToList();

    IEnumerable<Person> Siblings() => FamilyGraph.Get(person)./* your logic here */;
}


public static class PeopleExtensions 
{
    public static IEnumerable<Person> Parents(this IEnumerable<Person> people) =>
        people.SelectMany(person => person.Parents()).ToList();

    public static IEnumerable<Person> Siblings(this IEnumerable<Person> people) =>
        people.SelectMany(person => person.Siblings()).ToList();

    public static IEnumerable<Person> Children(this IEnumerable<Person> people) =>
        people.SelectMany(person => person.Children()).ToList();

}