So if you have ever gotten stuck with an interface that has callbacks you don’t like / don’t want where you are implementing. To save the day is callback pattern.
Imagine the following scenario. The example is logins.
If the user is logged in already just use those credentials;
If the user has a token from another system use those credentials;
If the user is domain authenticated use those credentials;
otherwise ask the user for login their credentials;
This chain can be achieved by composing the handlers so that when it hits the deepest level needed it succeeds and returns.
First you define two very straight forward interfaces.
namespace Core.Interfaces
{
public interface ICallbackHandler
{
ICallBack[] Handle(params ICallBack[] callBacks);
}
}
namespace Core.Interfaces
{
public interface ICallBack
{
bool Handled { get; set; }
}
}
Then you define the callback that you will need. This is a purely data class. No behavior.
using System.Windows.Forms;
using Core.Interfaces;
namespace Infrastructure.CallBacks
{
public class WarningCallBack : ICallBack
{
public readonly string WarningDescription;
public WarningCallBack(string warningDesc)
{
WarningDescription = warningDesc;
}
public bool Handled { get; set;}
}
}
The behavior is going to be brokered to the implementation specific to the client application by the handler.
public class Handler : ICallbackHandler
{
public ICallBack[] Handle(params ICallBack[] callBacks)
{
List<ICallBack> unhandledCallBacks = new List<ICallBack>();
foreach (ICallBack callBack in callBacks)
{
callBack.Handled = Handle((WarningCallBack)callBack);
if(!callBack.Handled)
{
unhandledCallBacks.Add(callBack);
}
}
return unhandledCallBacks.ToArray();
}
private bool Handle(WarningCallBack warningCallBack)
{
MessageBox.Show(warningCallBack.WarningDescription, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return true;
}
By returning unhandled callbacks you can compose these into a cache stack, or a handle stack.
This saved me a lot of time and ugliness in my code this morning. Thanks to David O’Hara and Craig Neuwirt
e6a76dd4-5368-4f36-82c0-2bb83634db69|0|.0
Design Patterns