Goals:
- In the Delphi programming language.
- An aspect that intercepts all virtual methods.
- A class whose constructor requires arguments.
- A Dependency Injection (DI) container that BOTH
- Creates an instance of the class, passing the correct arguments to the constructor.
- Applies the aspect to the instance so that all calls to virtual methods on the instance are intercepted.
I have made an attempt to do this with the Spring4D Container and Interception abstractions:
The below code outputs nothing. I would like similar code that outputs:
Intercepted one
Intercepted two
Intercepted three
unit Main;
interface
uses
Spring.Container,
Spring.Interception,
Spring.Services;
procedure Run;
type
TAspect = class(TInterfacedObject, IInterceptor)
public
procedure Intercept(const Invocation: IInvocation);
end;
TDependency = class(TObject)
procedure two; virtual;
end;
TTarget = class(TObject)
var FDependency: TDependency;
constructor Create(const Dependency: TDependency);
procedure one; virtual;
procedure three; virtual;
end;
implementation
procedure Run;
begin
GlobalContainer.RegisterType<TAspect>;
GlobalContainer.RegisterType<TDependency>.InterceptedBy<TAspect>;
GlobalContainer.RegisterType<TTarget>.InterceptedBy<TAspect>;
GlobalContainer.Build;
var Target := ServiceLocator.GetService<TTarget>;
Target.one;
end;
procedure TAspect.Intercept(const Invocation: IInvocation);
begin
Writeln('Intecepted ' + Invocation.Method.Name);
Invocation.Proceed;
end;
procedure TDependency.two;
begin
end;
constructor TTarget.Create(const Dependency: TDependency);
begin
inherited Create;
FDependency := Dependency;
end;
procedure TTarget.one;
begin
FDependency.two;
three;
end;
procedure TTarget.three;
begin
end;
end.
I tried something like this, and it intercepts ALL calls to virtual methods, but it doesn't meet all the goals listed above because it doesn't go through the DI container.
var Aspect: IInterceptor := TAspect.Create;
var Target := TProxyGenerator.CreateClassProxy<TTarget>([Aspect]);
I also tried using the container, but delegating to something that calls TProxyGenerator, and that intercepts ALL calls to virtual methods, but it doesn't meet all the goals listed above because it can only use the zero argument constructor (i.e. no constructor injection).