See below codes :
new ConditionCreator()
.Add()
.Or()
.Add()
.And()
.Add()
I want to create a Fluent Interface for that But I need, after Add() method developer see Only Or() or And() and after one of these, see Only Add() method.
so no one can write a code like :
new ConditionCreator()
.Add()
.Add()
.Add()
.Or()
.And()
.Add()
.And()
.And()
I want to have a limitation for some methods can accept special methods and etc. I can write all methods in one class and return this for each one but that is not suitable !!!
Please guide me How write Advanced Fluent Interface class.
To restrict things, you need to create and return one (of possibly several) "builder" objects that can do special operations, keeping a ref to the main class.
public class ConditionCreator
{
public ConditionCreator() { ... }
public SubConditionCreator Add() { ...; return new SubConditionCreator(this); }
internal ConditionCreator OnAdd() { ...; return this; };
internal ConditionCreator OnOr() { ...; return this; };
}
public class SubConditionCreator
{
private ConditionCreator _creator;
internal SubConditionCreator(ConditionCreator c) { _creator = c; }
public ConditionCreator And() { return _creator.OnAdd(); }
public ConditionCreator Or() { return _creator.OnOr(); }
}
Use internal access to restrict usage.
To avoid creating garbage, store a SubConditionCreator ref in main class
There is no real easy-way I know of to solve this. Perhaps T4 templating may help, but thus far I've always had to build-up the decision-tree, with an explicit interface at each node. For example; lets assume your decision tree is an infinite loop, then (implemented accordingly):
interface IStart<T>
{
IAndOr Add();
T End();
}
interface IAndOr<T>
{
IStart<T> And();
IStart<T> Or();
}
It gets difficult if you want a finite loop; say zero to two Adds:
interface IStart<T> : IFinish<T>
{
IAndOrFirst<T> Add();
}
interface IAndOrFirst<T>
{
ISecond<T> And();
ISecond<T> Or();
}
interface ISecond<T> : IFinish<T>
{
IAndOrSecond<T> Add();
}
interface IAndOrSecond <T>
{
IFinish<T> And();
IFinish<T> Or();
}
interface IFinish<T>
{
T End();
}
You can (explicitly) implement these in a single class that acts as the state machine:
class ConditionCreator <T> : IStart<T>, IFinish<T>, IAndOrFirst<T>, IAndOrSecond<T> {...}
where you'd return this
for Add()
And()
Or()
and maintain those state changes and order.
I'm hoping some answers this question with a better way that manually writing out each node.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With