Assuming there are following interfaces
public interface IRoot
{
IChildA ChildA { get; }
IChildB ChildB { get; }
}
public interface IChildA
{
IGrandChildA GrandChildA { get; }
IGrandChildB GrandChildB { get; }
}
public interface IChildB
{
IGrandChildC GrandChildC { get; }
}
public interface IGrandChildA
{
}
public interface IGrandChildB
{
}
public interface IGrandChildC
{
}
I would like to write fluent-style 'configurator' in order to keep interface associations. Everything should look like this:
private static void Test()
{
Configurator.Root<IRoot>()
.Join( _ => _.ChildA )
.Join( _ => _.GrandChildA )
.Up()
.Join( _ => _.GrandChildB )
.Up()
.Up()
.Join( _ => _.ChildB );
}
It is required to allow arbitrary nesting level of Join/Up pairs. Here is my attempt to declare such configurator.
public static class Configurator
{
public static IConfigBuilder<开发者_开发问答T, T> Root<T>()
{
return null;
}
}
public interface IConfigBuilder<P, T>
{
IConfigBuilder<T, C> Join<C>( Expression<Func<T, C>> expression );
IConfigBuilder<???, P> Up(); // This is the problem. How can I get grand-parent type?
}
It is unclear for me how I could remember all preceding nodes types. In other words, how to declare Up()
method? This reminds me old good Alexandrescu's type lists in C++. Is there any way to achieve the same in .net?
You would need at least two interfaces; and rather than return IConfigBuilder<...>
for Up
, trust the creating code to know what it created:
public interface IConfigBuilder<T>
{
IConfigBuilder<IConfigBuilder<T>, C> Join<C>(Expression<Func<T, C>> expression);
}
public interface IConfigBuilder<P, T> : IConfigBuilder<T>
{
P Up(); // This is the problem. How can I get grand-parent type?
new IConfigBuilder<IConfigBuilder<P, T>, C> Join<C>(Expression<Func<T, C>> expression);
}
精彩评论