Here is solution with actions and Func delegates, which do not use if...else structure. Actually this is a kind of Chain of Responsibility:
public class LicenseHandler
{
private readonly Func<GroupLicense, User, bool> predicate;
private readonly Action action;
private LicenseHandler nextHandler;
public LicenseHandler(Func<GroupLicense,User, bool> predicate, Action action)
{
this.action = action;
this.predicate = predicate;
}
public LicenseHandler SetNext(LicenseHandler handler)
{
nextHandler = handler;
return this;
}
public void Handle(GroupLicense license, User user)
{
if (predicate(license, user))
{
action();
return;
}
if (nextHandler != null)
nextHandler.Handle(license, user);
}
}
Create handlers and chain them:
var handler1 = new LicenseHandler((l, u) => l.IsEnabled && u.IsActive, Action1);
var handler2 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsActive, Action2);
var handler3 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsLocked, Action3);
handler1.SetNext(handler2.SetNext(handler3));
Processing looks like
handler1.Handle(licence, user);
People, who will support delegate-based code instead of simple if-else, accept my deepest sympathy.
UPDATE: If you want nice fluent API, then you can create builder class, which will create handlers chain:
public class LicenseHandlerBuilder
{
private LicenseHandler root;
private LicenseHandler current;
private LicenseHandlerBuilder() { }
public static LicenseHandlerBuilder CreateHandler(
Func<GroupLicense, User, bool> predicate, Action action)
{
var builder = new LicenseHandlerBuilder();
builder.root = new LicenseHandler(predicate, action);
builder.current = builder.root;
return builder;
}
public LicenseHandlerBuilder WithNext(
Func<GroupLicense, User, bool> predicate, Action action)
{
var next = new LicenseHandler(predicate, action);
current.SetNext(next);
current = next;
return this;
}
public LicenseHandler Build()
{
return root;
}
}
Usage:
var handler = LicenseHandlerBuilder
.CreateHandler((l, u) => l.IsEnabled && u.IsActive, Action1)
.WithNext((l, u) => !l.IsEnabled && u.IsActive, Action2)
.WithNext((l, u) => !l.IsEnabled && u.IsLocked, Action3)
.Build();