2017-09-23 3 views
1

、私はそれがサービスを解決できない場合は、別の容器に容器の代表者サービスの解像度を構築したいと思います - これらの線に沿って何か:Container1がTを解決できない場合は、Container1.Resolve <T>をContainer2.Resolve <T>に委任する方法? Spring4Dを使用して

function TContainer.Resolve<T>: T; 
begin 
    if not TryResolve<T>(Result) then 
    Result := OtherContainer.Resolve<T>; 
end; 

が、これは可能ですか?はいの場合、どうですか?


StackOverflowのは、私がそうでなければ、質問を投稿することはできないだろうと私は私のプロジェクト例を除外:「あなたの投稿は、ほとんどのコードであるように見えます。いくつかの詳細を追加してください」

答えて

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. 
をそれを達成する方法をいくつかの例のコードであります
関連する問題