构建接受方法组的流畅 API 方法

发布于 2024-12-23 02:47:40 字数 1010 浏览 2 评论 0原文

我正在尝试构建一个接受方法指示的流畅风格 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() 接受视图及其条目<的定义/em> / 退出方法。在上面的具体示例中,v1def 表示视图定义类,而 v1 表示实际的视图类。最终,一个新的转换被构建并添加到config中。

I'm trying to construct a fluent-style API that accepts indication of a method. What I want to achieve can be decribed with this (invalid) code sample:

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);
    }
}

The problem is the compiler obviously complains that x.SomeMethod denotes a method group. My API can presume neither the actual instance nor the actual method signature. This is to be decided on runtime.

How would you address this situation to provide an easy-to-use API that lets the user specify a method group?


Background: The resulting usage will be like this:

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

Where To() and From() accept definitions of views and their entry / exit methods. In the specific sample above v1def denotes a view definition class, while v1 denotes an actual view class. At the end of the day, a new transition is constructed and added into config.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天旳寂寞 2024-12-30 02:47:40

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

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

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

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

Unfortunately, there is simply no way to pass a method group as a parameter. As far as I'm aware, the CLR (as well as the various languages and everything in between) disallows passing around what would essentially be an untyped delegate... and because of method overloading, the scenario of multiple delegates with different signatures being represented by a method group name would have to be considered.

Because I don't know the details of how your view definition and view instance classes are structured or implemented, the best I can do is suggest the use of AOP through the use of attributes. If it could apply to your architecture, I would strongly suggest considering it; you can decorate your entry and exit methods with custom attributes, and use the decorations in your configuration class.

If your architecture doesn't lend itself to being augmented with AOP, the only remaining option you have is to go with a weakly-typed solution that uses strings when writing the configuration, and copious amounts of reflection when reading those strings back. I know it doesn't look like most of the other fluent APIs in .NET, but is this really so bad?

config.Transition().From(v1def, "ExitMethod").To(v2def, "EntryMethod");
愿与i 2024-12-30 02:47:40

一种方法是添加

public void SomeMethod() { }

Sample 类,并将 SampleBuilder.Method 签名更改为

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

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

One of the ways is to add

public void SomeMethod() { }

in the Sample class, and change SampleBuilder.Method signature to

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

This way you can capture name of the needed method (by passing method group which is converted to delegate instance) and choose proper overload.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文