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
.
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");