C# ListView/FlatList Builder

Date: 2023-02-23
public class FlatList
{
    public FlatList(IEnumerable<string> columns, List<List<object>> data, int totalCount)
    {
        Columns = columns;
        Data = data;
        TotalCount = totalCount;
    }

    public IEnumerable<string> Columns { get; }
    public List<List<object>> Data { get; }
    public int TotalCount { get; }
}

public class ColumnMetaData<T>
{
    public string Name { get; set; }
    public Func<T, object> ValueSelector { get; set; }
}

public class FlatListBuilder<T>
{
    private readonly List<ColumnMetaData<T>> Columns = new();

    public FlatListBuilder<T> AddColumn(string propertyName, Func<T, object> valueGetter)
    {
        var x = new ColumnMetaData<T>();
        x.Name = propertyName;
        x.ValueSelector = (y) =>
        {
            return valueGetter(y);
        };
        Columns.Add(x);
        return this;
    }

    public FlatList Build(IEnumerable<T> items, int? totalCount = null)
    {
        var data = items.Select(x => Columns.Select(y => y.ValueSelector(x)).ToList()).ToList();
        return new FlatList(Columns.Select(x => x.Name), data, totalCount ?? items.Count());
    }
}

// usage:
var flatListBuilder = new FlatListBuilder<VmLookupItem>()
    .AddColumn("id", x => x.Id)
    .AddColumn("name", x => x.Description)
    .AddColumn("additionalInfo", x => x.AdditionalInfo);
return flatListBuilder.Build(cachedItems);

Convert data back in typescript:

export interface IListView {
    columns: string[];
    data: Array<any[]>;
}

export function mapListView<T>(listView: IListView): T[] {
    const columns = listView.columns.map((name, i) => ({ index: i, name: name }));
    return listView.data.map((row) => {
        const item: any = {};
        for (const { index, name } of columns)
            item[name] = row[index];
        return item as T;
    });
}

async getAllDebtorArticles(debtorId: string): Promise<IDebtorArticle[]> {
    const listView = await appDependencies.IRestApi.request(`api/article/debtor/${debtorId}`).getData<IListView>();
    return mapListView<IDebtorArticle>(listView);
}

74400cookie-checkC# ListView/FlatList Builder