我想打電話GlobalContainer.ResolveAll<IFactory<TBob,IItem>>給我一個 IFactories 陣列,當它提供一個 TBob 時,我會回傳一個 IItem。
我將 IItems 注冊為
GlobalContainer.RegisterType<IItem,TA>('A');
GlobalContainer.RegisterType<IItem,TB>('B');
但我找不到注冊個別 IFactories 的方法,例如
GlobalContainer.RegisterType<IFactory<TBob,IItem>('AFac',['A']);
GlobalContainer.RegisterType<IFactory<TBob,IItem>('BFac',['B']);
因為沒有指定“注入”值的選項。
我能找到的唯一方法是為每個工廠提供如下代碼,但我確信必須有更清潔的方法。在下面的代碼中,我發現我必須使用 TFunc 而不是 IFactory,因為盡管它們實際上都是 TFunc,但我得到了一個 AV。
同樣通過執行此方法,如果 IItem 的建構式中有任何其他引數,我必須用 [Inject] 標記建構式,否則決議器會選擇繼承的建構式。
GlobalContainer.RegisterType<TFunc<TBob,IItem>>('AFac').DelegateTo(
function: TFunc<TBob,IItem>
begin
Result:=function(Bob: TBob): IItem
begin
Result:=GlobalContainer.Resolve<IItem>('A',[Bob]);
end;
end
);
uj5u.com熱心網友回復:
工廠是通過注冊的RegisterFactory,它們只支持帶有methodinfo($M 或繼承自IInvokable)的介面或啟用了methodinfo的匿名方法型別,例如Func<...>(推薦)來自Spring.pas(在2.0中引入)(不是TFunc<...>來自SysUtils.pas)。那是因為它使用引數 info 來動態構建工廠代碼。
您沒有明確說明,但我假設TAand的建構式TB看起來像這樣:
constructor Create(bob: TBob);
然后像這樣注冊它們(請記住,當所有代碼都在一個簡單的測驗 dpr 中時,這可能不起作用,因為它們在 dpr 內時會出現一些 typeinfo 故障) - 在容器中注冊的型別需要在一個單元中.
GlobalContainer.RegisterType<IItem, TA>('A');
GlobalContainer.RegisterType<IItem, TB>('B');
GlobalContainer.RegisterFactory<Func<TBob,IItem>>('AFactory', 'A', TParamResolution.ByType);
GlobalContainer.RegisterFactory<Func<TBob,IItem>>('BFactory', 'B', TParamResolution.ByType);
GlobalContainer.Build;
var factories := Globalcontainer.ResolveAll<Func<TBob,IItem>>;
for var factory in factories do
begin
var item := factory(nil);
Writeln((item as TObject).ClassName);
end;
這將列印:
TA
TB
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/447104.html
