Creating API That Is Fluent

Creating API that is fluent

This article explains it much better than I ever could.

EDIT, can't squeeze this in a comment...

There are two sides to interfaces, the implementation and the usage. There's more work to be done on the creation side, I agree with that, however the main benefits can be found on the usage side of things. Indeed, for me the main advantage of fluent interfaces is a more natural, easier to remember and use and why not, more aesthetically pleasing API. And just maybe, the effort of having to squeeze an API in a fluent form may lead to better thought out API?

As Martin Fowler says in the original article about fluent interfaces:

Probably the most important thing to
notice about this style is that the
intent is to do something along the
lines of an internal
DomainSpecificLanguage. Indeed this is
why we chose the term 'fluent' to
describe it, in many ways the two
terms are synonyms. The API is
primarily designed to be readable and
to flow. The price of this fluency is
more effort, both in thinking and in
the API construction itself. The
simple API of constructor, setter, and
addition methods is much easier to
write. Coming up with a nice fluent
API requires a good bit of thought.

As in most cases API's are created once and used over and over again, the extra effort may be worth it.

And verbose? I'm all for verbosity if it serves the readability of a program.

How to use Fluent API for creating a simple one-to-many relationship

The simple answer to your last question. EF is recognizing that Area.Id is a primary key so connects Location.AreaId to Area.Id

Also, here is a simple guide on how to do it.

C# Creating a Fluent API for chaining methods

You could implement something like this:

public class Fluent<TIn, TOut>
{
private readonly TIn _value;
private readonly Func<TIn, TOut> _func;

public Fluent(TIn value, Func<TIn, TOut> func)
{
_value = value;
_func = func;
}

public Fluent<TIn, TNewOut> Then<TNewOut>(Func<TOut, TNewOut> func)
=> new Fluent<TIn, TNewOut>(_value, x => func(_func(x)));

private TOut Calc() => _func(_value);

public static implicit operator TOut(Fluent<TIn, TOut> self) => self.Calc();
}

then you could chain multiple methods one after another and return what ever you want:

double f = new Fluent<int, int>(2, x => 2 * x)
.Then(x => 4 * x)
.Then(x => x / 0.5);
Tuple<double, double> t = new Fluent<int, int>(2, x => 2 * x)
.Then(x => new Tuple<double, double>(x,x));

n.b. You could also remove the overloaded implicit cast operator and make Calc method public. In that case, you could use var because there would be no ambiguity between Fluent<TIn, TOut> and TOut.

How are fluent API's different from other API's?

With a fluent interface you write methods that return the object that the method was invoked on (usually self or this) and handle traditional return values as a state change in that object. If you look at say some of the Javascript libraries that use a fluent interface it makes it far easier to deal with lists and nulls as they can be handled the same way you would a single object. The disadvantage of fluent interfaces is that they tend to create monolithic god objects that have a whole heap of responsibilities.

I wouldn't want them to be used everywhere (because of the god object problem) but they are nice from time to time.

jbpm create process using Fluent API?

Are you including in your code the dependency to jbpm-bpmn2 or any other implementation of the interface XmlProcessDumperFactoryService?

jbpm-bpmn2 has this one:

public class XmlProcessDumperFactoryServiceImpl implements XmlProcessDumperFactoryService {

public XmlProcessDumper newXmlProcessDumper() {
return XmlBPMNProcessDumper.INSTANCE;
}

}

How to build a Fluent Nested Guard API

The following function allows for a similar syntax to what you want.

public static GuardArgument<T> Property<T, TProp>(this GuardArgument<T> guardArgument, Func<T, TProp> getProperty, string propertyName, Action<GuardArgument<TProp>> validate)
{
GuardArgument<TProp> propertyGuardArgument = new GuardArgument<TProp>(getProperty(guardArgument.Value), propertyName);

validate(propertyGuardArgument);

return guardArgument;
}

The function creates a new GuardArgument for the selected property and then passes this into the Action parameter to allow you to validate as you wish.

This also allows infinite chaining of properties, although I'm not sure that would be particularly readable.

Usage:

Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(x => x.ChildProp1, "childProp1", childProp1 =>
childProp1.IsNotNull()
.IsLessThan(10)
.Property(y => y.InnerChildProperty, "innerChildProperty", innerChildProperty =>
innerChildProperty.IsNotNull()
)
)
.Property(x => x.ChildProp2, "childProp2", childProp2 =>
childProp2.IsNotNull()
.IsGreaterThan(10)
);


Related Topics



Leave a reply



Submit