使用Spring4D,我想建立一个容器,将服务解析委托给另一个容器,如果它无法解析服务 - 这就是这些:
function TContainer.Resolve<T>: T;
begin
if not TryResolve<T>(Result) then
Result := OtherContainer.Resolve<T>;
end;
这可能吗?
答案 0 :(得分:1)
在处理特定类型或类型模式的容器中有所谓的子依赖关系解析器(未来版本将只调用它们类型解析器)(比如能够解析TArray<T>
或IList<T>
其中T是什么正在注册)。
您可以实现自己的检查,如果某个类型不在您将此解析器附加到的容器内,然后将此类型的解析链委托给另一个容器。
以下是一些示例代码如何实现(不释放对象)
uses
Spring,
Spring.Container,
Spring.Container.Core,
System.SysUtils;
type
TFoo = class
end;
TBar = class
private
fFoo: TFoo;
public
constructor Create(const foo: TFoo);
property Foo: TFoo read fFoo;
end;
TSubContainerResolver = class(TInterfacedObject, ISubDependencyResolver)
private
fContainer: TContainer;
fSubContainer: TContainer;
public
constructor Create(const container, subContainer: TContainer);
function CanResolve(const context: ICreationContext;
const dependency: TDependencyModel; const argument: TValue): Boolean;
function Resolve(const context: ICreationContext;
const dependency: TDependencyModel; const argument: TValue): TValue;
end;
{ TBar }
constructor TBar.Create(const foo: TFoo);
begin
fFoo := foo;
end;
{ TSubContainerResolver }
constructor TSubContainerResolver.Create(const container, subContainer: TContainer);
begin
fContainer := container;
fSubContainer := subContainer;
end;
function TSubContainerResolver.CanResolve(const context: ICreationContext;
const dependency: TDependencyModel; const argument: TValue): Boolean;
begin
Result := not fContainer.Kernel.Registry.HasService(dependency.TypeInfo)
and fSubContainer.Kernel.Resolver.CanResolve(context, dependency, argument);
end;
function TSubContainerResolver.Resolve(const context: ICreationContext;
const dependency: TDependencyModel; const argument: TValue): TValue;
begin
Result := fSubContainer.Kernel.Resolver.Resolve(context, dependency, argument);
end;
procedure ScenarioOne;
var
c1, c2: TContainer;
b: TBar;
begin
c1 := TContainer.Create;
c2 := TContainer.Create;
c1.Kernel.Resolver.AddSubResolver(TSubContainerResolver.Create(c1, c2));
// dependency in subcontainer
c1.RegisterType<TBar>;
c1.Build;
c2.RegisterType<TFoo>;
c2.Build;
b := c1.Resolve<TBar>;
Assert(Assigned(b.fFoo));
end;
procedure ScenarioTwo;
var
c1, c2: TContainer;
b: TBar;
begin
c1 := TContainer.Create;
c2 := TContainer.Create;
c1.Kernel.Resolver.AddSubResolver(TSubContainerResolver.Create(c1, c2));
c2.Kernel.Resolver.AddSubResolver(TSubContainerResolver.Create(c2, c1));
// type in subcontainer but dependency in parent container
c1.RegisterType<TFoo>;
c1.Build;
c2.RegisterType<TBar>;
c2.Build;
b := c1.Resolve<TBar>;
Assert(Assigned(b.fFoo));
end;
begin
ScenarioOne;
ScenarioTwo;
end.