Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Configurable polymorphic fluent interface in C#
using System;
using System.Collections.Generic;
namespace ConfigurablePolymorphicFluentInterface
{
public class Program
{
static void Main(string[] args)
{
string s = ListEnrollmentsSelectBuilder.Create()
.Data()
.HistoryOn(new DateTime(2016, 6, 1))
.Course(x => x.Data().HistoryInRange(new DateTime(2016, 5, 1), new DateTime(2016, 6, 1)))
.Domain()
.User(x => x.Session().Data().AllHistory())
.Metrics(x => x.AllHistory());
Console.WriteLine(s);
string t = ListEnrollmentsSelectBuilder.Create()
.Data()
.Domain()
.AllHistory()
.HistoryOn(new DateTime(2014, 3, 2))
.HistoryInRange(new DateTime(2015, 1, 2), new DateTime(2015, 1, 6))
.Course(x => x.Data()
.AllHistory()
.HistoryOn(new DateTime(2014, 3, 2))
.HistoryInRange(new DateTime(2015, 1, 2), new DateTime(2015, 1, 6)))
.User(x => x.Data()
.Session()
.AllHistory()
.HistoryOn(new DateTime(2014, 3, 2))
.HistoryInRange(new DateTime(2015, 1, 2), new DateTime(2015, 1, 6)))
.Metrics(x => x.AllHistory()
.HistoryOn(new DateTime(2014, 3, 2))
.HistoryInRange(new DateTime(2015, 1, 2), new DateTime(2015, 1, 6)));
Console.WriteLine(t);
}
}
public class SelectBuilder
{
public List<string> SelectItems { get; }
public SelectBuilder()
{
SelectItems = new List<string>();
}
public string Build()
{
return string.Join(",", SelectItems);
}
internal void AddSubBuilder<TSelectBuilder>(Action<TSelectBuilder> action)
where TSelectBuilder : SelectBuilder, new()
{
var selectBuilder = new TSelectBuilder();
action(selectBuilder);
SelectItems.AddRange(selectBuilder.SelectItems);
}
public static implicit operator string(SelectBuilder d)
{
return d.Build();
}
}
public class SelectBuilder<T> : SelectBuilder
{
public static SelectBuilder<T> Create()
{
return new SelectBuilder<T>();
}
}
public class ListEnrollmentsSelectBuilder : SelectBuilder<ListEnrollmentsSelectBuilder>,
IWithData,
IWithDomain,
IWithHistory,
IWithCourse,
IWithCourseBuilder, IWithCourseData, IWithCourseHistory,
IWithUser,
IWithUserBuilder,
IWithUserData, IWithUserHistory, IWithUserSession,
IWithMetrics,
IWithMetricsBuilder, IWithMetricsHistory
{
}
public class ListCoursesSelectBuilder : SelectBuilder<ListCoursesSelectBuilder>,
IWithData,
IWithHistory,
IWithDomain,
IWithDomainBuilder, IWithDomainData,
IWithBase,
IWithBaseBuilder, IWithBaseData,
IWithEnrollmentMetrics
{
}
public class DomainSelectBuilder<T> : SelectBuilder { }
public class CourseSelectBuilder<T> : SelectBuilder { }
public class UserSelectBuilder<T> : SelectBuilder { }
public class BaseSelectBuilder<T> : SelectBuilder { }
public class MetricsSelectBuilder<T> : SelectBuilder { }
public interface IWithData { }
public interface IWithDomain { }
public interface IWithDomainBuilder { }
public interface IWithDomainData { }
public interface IWithCourse { }
public interface IWithCourseBuilder { }
public interface IWithCourseData { }
public interface IWithCourseHistory { }
public interface IWithHistory { }
public interface IWithEnrollmentMetrics { }
public interface IWithMetrics { }
public interface IWithMetricsBuilder { }
public interface IWithMetricsHistory { }
public interface IWithUser { }
public interface IWithUserBuilder { }
public interface IWithUserData { }
public interface IWithUserSession { }
public interface IWithUserHistory { }
public interface IWithBase { }
public interface IWithBaseBuilder { }
public interface IWithBaseData { }
public static class SelectBuilderExtensions
{
public static SelectBuilder<T> Data<T>(this SelectBuilder<T> builder) where T : IWithData
{
builder.SelectItems.Add("data");
return builder;
}
public static SelectBuilder<T> Course<T>(this SelectBuilder<T> builder) where T : IWithCourse
{
builder.SelectItems.Add("course");
return builder;
}
public static SelectBuilder<T> Course<T>(this SelectBuilder<T> builder, Action<CourseSelectBuilder<T>> action) where T : IWithCourseBuilder
{
builder.SelectItems.Add("course");
builder.AddSubBuilder(action);
return builder;
}
public static SelectBuilder<T> Domain<T>(this SelectBuilder<T> builder) where T : IWithDomain
{
builder.SelectItems.Add("domain");
return builder;
}
public static SelectBuilder<T> Domain<T>(this SelectBuilder<T> builder, Action<DomainSelectBuilder<T>> action) where T : IWithDomainBuilder
{
builder.SelectItems.Add("domain");
builder.AddSubBuilder(action);
return builder;
}
public static SelectBuilder<T> User<T>(this SelectBuilder<T> builder) where T : IWithUser
{
builder.SelectItems.Add("user");
return builder;
}
public static SelectBuilder<T> User<T>(this SelectBuilder<T> builder, Action<UserSelectBuilder<T>> action) where T : IWithUserBuilder
{
builder.SelectItems.Add("user");
builder.AddSubBuilder(action);
return builder;
}
public static SelectBuilder<T> Base<T>(this SelectBuilder<T> builder) where T : IWithBase
{
builder.SelectItems.Add("base");
return builder;
}
public static SelectBuilder<T> Base<T>(this SelectBuilder<T> builder, Action<BaseSelectBuilder<T>> action) where T : IWithBaseBuilder
{
builder.SelectItems.Add("base");
builder.AddSubBuilder(action);
return builder;
}
public static SelectBuilder<T> EnrollmentMetrics<T>(this SelectBuilder<T> builder) where T : IWithEnrollmentMetrics
{
builder.SelectItems.Add("enrollmentmetrics");
return builder;
}
public static SelectBuilder<T> Metrics<T>(this SelectBuilder<T> builder) where T : IWithMetrics
{
builder.SelectItems.Add("metrics");
return builder;
}
public static SelectBuilder<T> Metrics<T>(this SelectBuilder<T> builder, Action<MetricsSelectBuilder<T>> action) where T : IWithMetricsBuilder
{
builder.SelectItems.Add("metrics");
builder.AddSubBuilder(action);
return builder;
}
public static SelectBuilder<T> AllHistory<T>(this SelectBuilder<T> builder) where T : IWithHistory
{
builder.SelectItems.Add("history(all)");
return builder;
}
public static SelectBuilder<T> HistoryOn<T>(this SelectBuilder<T> builder, DateTime date) where T : IWithHistory
{
builder.SelectItems.Add($"history(on,{date.SelectFormat()})");
return builder;
}
public static SelectBuilder<T> HistoryInRange<T>(this SelectBuilder<T> builder, DateTime from, DateTime to) where T : IWithHistory
{
builder.SelectItems.Add($"history(range,{from.SelectFormat()}{to.SelectFormat()})");
return builder;
}
}
public static class DomainSelectBuilderExtensions
{
public static DomainSelectBuilder<T> Data<T>(this DomainSelectBuilder<T> builder) where T : IWithDomainData
{
builder.SelectItems.Add("domain.data");
return builder;
}
}
public static class BaseSelectBuilderExtensions
{
public static BaseSelectBuilder<T> Data<T>(this BaseSelectBuilder<T> builder) where T : IWithBaseData
{
builder.SelectItems.Add("base.data");
return builder;
}
}
public static class CourseSelectBuilderExtensions
{
public static CourseSelectBuilder<T> Data<T>(this CourseSelectBuilder<T> builder) where T : IWithCourseData
{
builder.SelectItems.Add("course.data");
return builder;
}
public static CourseSelectBuilder<T> AllHistory<T>(this CourseSelectBuilder<T> builder) where T : IWithCourseHistory
{
builder.SelectItems.Add("course.history(all)");
return builder;
}
public static CourseSelectBuilder<T> HistoryOn<T>(this CourseSelectBuilder<T> builder, DateTime date) where T : IWithCourseHistory
{
builder.SelectItems.Add($"course.history(on,{date.SelectFormat()})");
return builder;
}
public static CourseSelectBuilder<T> HistoryInRange<T>(this CourseSelectBuilder<T> builder, DateTime from, DateTime to) where T : IWithCourseHistory
{
builder.SelectItems.Add($"course.history(range,{from.SelectFormat()},{to.SelectFormat()})");
return builder;
}
}
public static class MetricsSelectBuilderExtensions
{
public static MetricsSelectBuilder<T> AllHistory<T>(this MetricsSelectBuilder<T> builder) where T : IWithCourseHistory
{
builder.SelectItems.Add("metrics.history(all)");
return builder;
}
public static MetricsSelectBuilder<T> HistoryOn<T>(this MetricsSelectBuilder<T> builder, DateTime date) where T : IWithCourseHistory
{
builder.SelectItems.Add($"metrics.history(on,{date.SelectFormat()})");
return builder;
}
public static MetricsSelectBuilder<T> HistoryInRange<T>(this MetricsSelectBuilder<T> builder, DateTime from, DateTime to) where T : IWithCourseHistory
{
builder.SelectItems.Add($"metrics.history(range,{from.SelectFormat()},{to.SelectFormat()})");
return builder;
}
}
public static class UserSelectBuilderExtensions
{
public static UserSelectBuilder<T> Data<T>(this UserSelectBuilder<T> builder) where T : IWithUserData
{
builder.SelectItems.Add("user.data");
return builder;
}
public static UserSelectBuilder<T> Session<T>(this UserSelectBuilder<T> builder) where T : IWithUserSession
{
builder.SelectItems.Add("user.session");
return builder;
}
public static UserSelectBuilder<T> AllHistory<T>(this UserSelectBuilder<T> builder) where T : IWithUserHistory
{
builder.SelectItems.Add("user.history(all)");
return builder;
}
public static UserSelectBuilder<T> HistoryOn<T>(this UserSelectBuilder<T> builder, DateTime date) where T : IWithUserHistory
{
builder.SelectItems.Add($"user.history(on,{date.SelectFormat()})");
return builder;
}
public static UserSelectBuilder<T> HistoryInRange<T>(this UserSelectBuilder<T> builder, DateTime from, DateTime to) where T : IWithUserHistory
{
builder.SelectItems.Add($"user.history(range,{from.SelectFormat()},{to.SelectFormat()})");
return builder;
}
}
public static class DateTimeExtensions
{
public static string SelectFormat(this DateTime dateTime)
{
return dateTime.ToString("s") + "Z";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.