构造一个接受方法组的流畅API方法

时间:2011-12-26 22:52:40

标签: c# expression-trees fluent-interface

我正在尝试构建一个接受方法指示的流畅式API。我想要实现的是这个(无效的)代码示例:

public class SampleBuilder
{
    public void Method<T>(Expression<Func<T, Delegate>> func) { }
    // for the sake of this example this method doesn't have a return value
}

public class Sample
{
    public void SomeMethod(int some, int arbitrary, int agruments) { }
}

public class SampleConfig
{
    public void Config()
    {
        new SampleBuilder().Method<Sample>(x => x.SomeMethod);
    }
}

问题是编译器明显抱怨x.SomeMethod表示方法组。我的API既不能设定实际实例,也不能设定实际的方法签名。这将在运行时决定。

您如何解决这种情况,提供一个易于使用的API,让用户指定一个方法组?


背景:结果用法如下:

config.Transition().From(v1def, v1 => v1.ExitMethod).To(v2def, v2 => v2.EntryMethod);

其中To()From()接受视图的定义及其条目 / 退出方法。在上面的特定示例中,v1def表示视图定义类,而v1表示实际视图类。在一天结束时,会构建一个新的过渡并添加到config

2 个答案:

答案 0 :(得分:1)

不幸的是,根本无法将方法组作为参数传递。据我所知,CLR(以及各种语言和介于两者之间的所有内容)不允许传递基本上是无类型委托的内容......并且由于方法重载,具有不同签名的多个代表的场景是必须考虑由方法组名称表示。

因为我不知道您的视图定义和视图实例类的结构或实现方式的详细信息,所以我能做的最好的事情是建议使用AOP来使用attributes。如果它可以适用于您的架构,我强烈建议考虑它;您可以使用自定义属性修饰入口和出口方法,并使用配置类中的装饰。

如果您的体系结构不适合使用AOP进行扩充,那么您唯一剩下的选择就是使用在编写配置时使用字符串的弱类型解决方案,以及在读取这些字符串时的大量反射。我知道它看起来不像.NET中的大多数其他流畅的API,但这真的很糟糕吗?

config.Transition().From(v1def, "ExitMethod").To(v2def, "EntryMethod");

答案 1 :(得分:0)

其中一种方法是添加

public void SomeMethod() { }
在Sample类中

,并将SampleBuilder.Method签名更改为

public void Method<T>(Expression<Func<T, Action>> func) { }

这样,您可以捕获所需方法的名称(通过传递转换为委托实例的方法组)并选择适当的重载。