unit Unit1;
interface
uses
{System.}Generics.Collections,
{System.}SysUtils;
type
TObjectHandler =
class abstract
private type
TAction = TProc<TObject>;
private
FRoutes: TDictionary<TClass, TAction>;
protected type
TRoute<T> =
procedure( Argument: T )
of object;
protected
procedure RegisterRoute<T:
class>( ARoute: TRoute<T> );
procedure DoRaise( Argument: TObject );
end;
TFoo =
class
end;
TBar =
class
end;
TFooBar =
class( TObjectHandler )
private
procedure Apply( Argument: TFoo );
overload;
procedure Apply( Argument: TBar );
overload;
public
constructor Create( );
procedure Handle( Argument: TObject );
end;
implementation
{ TObjectHandler }
procedure TObjectHandler.DoRaise( Argument: TObject );
var
LAction: TAction;
begin
if FRoutes.TryGetValue( Argument.ClassType, LAction )
then
LAction( Argument )
else
raise ENotImplemented.CreateFmt( '
Handler für %s fehlt', [ Argument.ClassName ] );
end;
procedure TObjectHandler.RegisterRoute<T>( ARoute: TRoute<T> );
begin
FRoutes.Add( T,
procedure( Argument: TObject )
begin
ARoute( Argument
as T );
end );
end;
{ TFooBar }
procedure TFooBar.Apply( Argument: TFoo );
begin
end;
procedure TFooBar.Apply( Argument: TBar );
begin
end;
constructor TFooBar.Create;
begin
inherited Create;
RegisterRoute<TFoo>( Apply );
RegisterRoute<TBar>( Apply );
end;
procedure TFooBar.Handle( Argument: TObject );
begin
DoRaise( Argument );
end;
end.