Извлекать свойства из вложенных коллекций типа с помощью Fluent Syntax - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь создать способ добавления в коллекцию свойств, выбранных из типа с использованием синтаксиса Fluent.В настоящее время у меня есть следующее:

SelectablePropertiesBuilder

public class SelectablePropertiesBuilder<T>
{

    #region Fields

    private const char SEPARATOR_CHAR = ',';

    private List<PropertyInfo> _propertiesSelected;

    #endregion


    #region Properties

    public char GetSeparator => SEPARATOR_CHAR;

    public int Count => _propertiesSelected.Count;

    #endregion


    #region Constructor

    internal SelectablePropertiesBuilder()
    {
        _propertiesSelected = new List<PropertyInfo>();
    }

    public static T InitBuilder() => (T)Activator.CreateInstance(typeof(T));

    #endregion


    #region Public methods

    public void AddSelected(PropertyInfo propertyInfo)
    {
        _propertiesSelected.Add(propertyInfo);
    }

    public string FormatSelection()
    {
        var stringBuilder = new StringBuilder();

        IteratePropertiesForBuilder(stringBuilder);

        return stringBuilder.ToString();
    }

    #endregion


    #region Private methods

    private void IteratePropertiesForBuilder(StringBuilder stringBuilder)
    {
        int currentIndex = 1, totalCount = _propertiesSelected.Count;

        foreach (var prop in _propertiesSelected)
        {
            stringBuilder.Append(prop.Name);

            if (currentIndex < totalCount)
                stringBuilder.Append(SEPARATOR_CHAR);

            currentIndex++;
        }
    }

    #endregion

}

Методы расширения

    public static SelectablePropertiesBuilder<T> SelectProperty<T, TProperty>(this T objectSource, Expression<Func<T, TProperty>> navigationPropertyPath)
    {
        var propertyInfo = GetPropertyInfo(navigationPropertyPath);

        var builder = new SelectablePropertiesBuilder<T>();
        builder.AddSelected(propertyInfo);

        return builder;
    }

    public static SelectablePropertiesBuilder<T> ThenSelectProperty<T, TProperty>(this SelectablePropertiesBuilder<T> builder, Expression<Func<T, TProperty>> navigationPropertyPath)
    {
        var propertyInfo = GetPropertyInfo(navigationPropertyPath);

        builder.AddSelected(propertyInfo);

        return builder;
    }

    private static PropertyInfo GetPropertyInfo<T, TProperty>(Expression<Func<T, TProperty>> navigationPropertyPath)
    {
        var member = (MemberExpression)navigationPropertyPath.Body;
        var propertyName = member.Member.Name;
        var propertyInfo = new PropertyInfo { Name = propertyName };

        return propertyInfo;
    }

Работает полностьюМетод UnitTest:

        [TestMethod]
    public void Given_ExternalTypeWithNestedCollection_WhenFormatSelectionInvoked_ThenStringFormattedRetrived()
    {
        var propertiesFormatted = SelectablePropertiesBuilder<TestClass>.InitBuilder()
           .SelectProperty(x => x.TestPropertyStr)
           .ThenSelectProperty(x => x.TestPropertyInt)
           .FormatSelection();

        Assert.IsFalse(string.IsNullOrEmpty(propertiesFormatted));
        Assert.IsTrue(propertiesFormatted.LastIndexOf(',') != propertiesFormatted.Length);
    }

Ну, теперь это работает, но мне нужно выбрать свойства во вложенных коллекциях.В настоящее время я не могу этого сделать, и я заблокирован, как я могу добавить эту функциональность, используя тот же синтаксис.

¿Любые идеи?

Заранее спасибо

PD: полный репозиторий реализации внутри ChustaSoft.Common NuGet здесь :

1 Ответ

0 голосов
/ 12 декабря 2018

Наконец-то я нашел способ достичь своей цели, используя singleton и унаследованный SelectablePropertiesBuilder.Я также улучшил синтаксис, вы можете увидеть полную реализацию здесь:

...