Quick.IOC.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. { ***************************************************************************
  2. Copyright (c) 2016-2020 Kike Pérez
  3. Unit : Quick.IoC
  4. Description : IoC Dependency Injector
  5. Author : Kike Pérez
  6. Version : 1.0
  7. Created : 19/10/2019
  8. Modified : 08/02/2020
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.IoC;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. System.SysUtils,
  26. RTTI,
  27. System.TypInfo,
  28. System.Generics.Collections,
  29. Quick.Logger.Intf,
  30. Quick.Options;
  31. type
  32. TActivatorDelegate<T> = reference to function: T;
  33. TIocRegistration = class
  34. type
  35. TRegisterMode = (rmTransient, rmSingleton, rmScoped);
  36. private
  37. fRegisterMode : TRegisterMode;
  38. fIntfInfo : PTypeInfo;
  39. fImplementation : TClass;
  40. fActivatorDelegate : TActivatorDelegate<TValue>;
  41. public
  42. constructor Create;
  43. property IntfInfo : PTypeInfo read fIntfInfo write fIntfInfo;
  44. property &Implementation : TClass read fImplementation write fImplementation;
  45. function IsSingleton : Boolean;
  46. function IsTransient : Boolean;
  47. function IsScoped : Boolean;
  48. function AsSingleton : TIocRegistration;
  49. function AsTransient : TIocRegistration;
  50. function AsScoped : TIocRegistration;
  51. property ActivatorDelegate : TActivatorDelegate<TValue> read fActivatorDelegate write fActivatorDelegate;
  52. end;
  53. TIocRegistrationInterface = class(TIocRegistration)
  54. private
  55. fInstance : IInterface;
  56. public
  57. property Instance : IInterface read fInstance write fInstance;
  58. end;
  59. TIocRegistrationInstance = class(TIocRegistration)
  60. private
  61. fInstance : TObject;
  62. public
  63. property Instance : TObject read fInstance write fInstance;
  64. end;
  65. TIocRegistration<T> = record
  66. private
  67. fRegistration : TIocRegistration;
  68. public
  69. constructor Create(aRegistration : TIocRegistration);
  70. function AsSingleton : TIocRegistration<T>;
  71. function AsTransient : TIocRegistration<T>;
  72. function AsScoped : TIocRegistration<T>;
  73. function DelegateTo(aDelegate : TActivatorDelegate<T>) : TIocRegistration<T>;
  74. end;
  75. IIocRegistrator = interface
  76. ['{F3B79B15-2874-4B66-9B7F-06E2EBFED1AE}']
  77. function GetKey(aPInfo : PTypeInfo; const aName : string = ''): string;
  78. function RegisterType(aTypeInfo : PTypeInfo; aImplementation : TClass; const aName : string = '') : TIocRegistration;
  79. function RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration;
  80. end;
  81. TIocRegistrator = class(TInterfacedObject,IIocRegistrator)
  82. private
  83. fDependencies : TDictionary<string,TIocRegistration>;
  84. public
  85. constructor Create;
  86. destructor Destroy; override;
  87. property Dependencies : TDictionary<string,TIocRegistration> read fDependencies write fDependencies;
  88. function IsRegistered<TInterface: IInterface; TImplementation: class>(const aName : string = '') : Boolean; overload;
  89. function IsRegistered<TInterface : IInterface>(const aName : string = '') : Boolean; overload;
  90. function GetKey(aPInfo : PTypeInfo; const aName : string = ''): string;
  91. function RegisterType<TInterface: IInterface; TImplementation: class>(const aName : string = '') : TIocRegistration<TImplementation>; overload;
  92. function RegisterType(aTypeInfo : PTypeInfo; aImplementation : TClass; const aName : string = '') : TIocRegistration; overload;
  93. function RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration; overload;
  94. function RegisterInstance<T : class>(const aName : string = '') : TIocRegistration<T>; overload;
  95. function RegisterInstance<TInterface : IInterface>(aInstance : TInterface; const aName : string = '') : TIocRegistration; overload;
  96. function RegisterOptions<T : TOptions>(aOptions : T) : TIocRegistration<T>;
  97. end;
  98. IIocContainer = interface
  99. ['{6A486E3C-C5E8-4BE5-8382-7B9BCCFC1BC3}']
  100. function RegisterType(aInterface: PTypeInfo; aImplementation : TClass; const aName : string = '') : TIocRegistration;
  101. function RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration;
  102. function Resolve(aServiceType: PTypeInfo; const aName : string = ''): TValue;
  103. //procedure Build;
  104. end;
  105. IIocInjector = interface
  106. ['{F78E6BBC-2A95-41C9-B231-D05A586B4B49}']
  107. end;
  108. TIocInjector = class(TInterfacedObject,IIocInjector)
  109. end;
  110. IIocResolver = interface
  111. ['{B7C07604-B862-46B2-BF33-FF941BBE53CA}']
  112. function Resolve(aServiceType: PTypeInfo; const aName : string = ''): TValue; overload;
  113. end;
  114. TIocResolver = class(TInterfacedObject,IIocResolver)
  115. private
  116. fRegistrator : TIocRegistrator;
  117. fInjector : TIocInjector;
  118. function CreateInstance(aClass : TClass) : TValue;
  119. public
  120. constructor Create(aRegistrator : TIocRegistrator; aInjector : TIocInjector);
  121. function Resolve<T>(const aName : string = ''): T; overload;
  122. function Resolve(aServiceType: PTypeInfo; const aName : string = ''): TValue; overload;
  123. end;
  124. TIocContainer = class(TInterfacedObject,IIocContainer)
  125. private
  126. fRegistrator : TIocRegistrator;
  127. fResolver : TIocResolver;
  128. fInjector : TIocInjector;
  129. fLogger : ILogger;
  130. function InterfaceTypeInfo(const AGUID : TGUID) : PTypeInfo;
  131. class var
  132. GlobalInstance: TIocContainer;
  133. protected
  134. class constructor Create;
  135. class destructor Destroy;
  136. public
  137. constructor Create;
  138. destructor Destroy; override;
  139. function IsRegistered<TInterface: IInterface; TImplementation: class>(const aName: string): Boolean; overload;
  140. function IsRegistered<TInterface : IInterface>(const aName: string): Boolean; overload;
  141. function RegisterType<TInterface: IInterface; TImplementation: class>(const aName : string = '') : TIocRegistration<TImplementation>; overload;
  142. function RegisterType(aInterface: PTypeInfo; aImplementation : TClass; const aName : string = '') : TIocRegistration; overload;
  143. function RegisterInstance<T : class>(const aName: string = ''): TIocRegistration<T>; overload;
  144. function RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration; overload;
  145. function RegisterInstance<TInterface : IInterface>(aInstance : TInterface; const aName : string = '') : TIocRegistration; overload;
  146. function RegisterOptions<T : TOptions>(aOptions : TOptions) : TIocRegistration<T>;
  147. function Resolve<T>(const aName : string = ''): T; overload;
  148. function Resolve(aServiceType: PTypeInfo; const aName : string = ''): TValue; overload;
  149. function AbstractFactory<T : class, constructor>(aClass : TClass) : T;
  150. end;
  151. EIocRegisterError = class(Exception);
  152. EIocResolverError = class(Exception);
  153. //singleton global instance
  154. function GlobalContainer: TIocContainer;
  155. implementation
  156. function GlobalContainer: TIocContainer;
  157. begin
  158. Result := TIocContainer.GlobalInstance;
  159. end;
  160. { TIocRegistration }
  161. constructor TIocRegistration.Create;
  162. begin
  163. fRegisterMode := TRegisterMode.rmTransient;
  164. end;
  165. function TIocRegistration.AsTransient: TIocRegistration;
  166. begin
  167. Result := Self;
  168. fRegisterMode := TRegisterMode.rmTransient;
  169. end;
  170. function TIocRegistration.AsSingleton : TIocRegistration;
  171. begin
  172. Result := Self;
  173. fRegisterMode := TRegisterMode.rmSingleton;
  174. end;
  175. function TIocRegistration.AsScoped: TIocRegistration;
  176. begin
  177. Result := Self;
  178. fRegisterMode := TRegisterMode.rmScoped;
  179. end;
  180. function TIocRegistration.IsTransient: Boolean;
  181. begin
  182. Result := fRegisterMode = TRegisterMode.rmTransient;
  183. end;
  184. function TIocRegistration.IsSingleton: Boolean;
  185. begin
  186. Result := fRegisterMode = TRegisterMode.rmSingleton;
  187. end;
  188. function TIocRegistration.IsScoped: Boolean;
  189. begin
  190. Result := fRegisterMode = TRegisterMode.rmScoped;
  191. end;
  192. { TIocContainer }
  193. class constructor TIocContainer.Create;
  194. begin
  195. GlobalInstance := TIocContainer.Create;
  196. end;
  197. class destructor TIocContainer.Destroy;
  198. begin
  199. if GlobalInstance <> nil then GlobalInstance.Free;
  200. inherited;
  201. end;
  202. function TIocContainer.AbstractFactory<T>(aClass: TClass): T;
  203. begin
  204. Result := fResolver.CreateInstance(aClass).AsType<T>;
  205. end;
  206. constructor TIocContainer.Create;
  207. begin
  208. fLogger := nil;
  209. fRegistrator := TIocRegistrator.Create;
  210. fInjector := TIocInjector.Create;
  211. fResolver := TIocResolver.Create(fRegistrator,fInjector);
  212. end;
  213. destructor TIocContainer.Destroy;
  214. begin
  215. fInjector.Free;
  216. fResolver.Free;
  217. fRegistrator.Free;
  218. fLogger := nil;
  219. inherited;
  220. end;
  221. function TIocContainer.InterfaceTypeInfo(const AGUID : TGUID) : PTypeInfo;
  222. var
  223. ctx : TRttiContext;
  224. rtype : TRttiType;
  225. rtypei : TRttiInterfaceType;
  226. begin
  227. ctx := TRttiContext.Create;
  228. try
  229. for rtype in ctx.GetTypes do
  230. begin
  231. if rtype.TypeKind = TTypeKind.tkInterface then
  232. begin
  233. rtypei := (rtype as TRttiInterfaceType);
  234. if IsEqualGUID(rtypei.GUID,AGUID) then Exit(rtypei.Handle);
  235. end;
  236. end;
  237. finally
  238. ctx.Free;
  239. end;
  240. Result := nil;
  241. end;
  242. function TIocContainer.IsRegistered<TInterface, TImplementation>(const aName: string): Boolean;
  243. begin
  244. Result := fRegistrator.IsRegistered<TInterface,TImplementation>(aName);
  245. end;
  246. function TIocContainer.IsRegistered<TInterface>(const aName: string): Boolean;
  247. begin
  248. Result := fRegistrator.IsRegistered<TInterface>(aName);
  249. end;
  250. function TIocContainer.RegisterType<TInterface, TImplementation>(const aName: string): TIocRegistration<TImplementation>;
  251. begin
  252. Result := fRegistrator.RegisterType<TInterface, TImplementation>(aName);
  253. end;
  254. function TIocContainer.RegisterType(aInterface: PTypeInfo; aImplementation: TClass; const aName: string): TIocRegistration;
  255. begin
  256. Result := fRegistrator.RegisterType(aInterface,aImplementation,aName);
  257. end;
  258. function TIocContainer.RegisterInstance<T>(const aName: string): TIocRegistration<T>;
  259. begin
  260. Result := fRegistrator.RegisterInstance<T>(aName);
  261. end;
  262. function TIocContainer.RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration;
  263. begin
  264. Result := fRegistrator.RegisterInstance(aTypeInfo,aName);
  265. end;
  266. function TIocContainer.RegisterInstance<TInterface>(aInstance: TInterface; const aName: string): TIocRegistration;
  267. begin
  268. Result := fRegistrator.RegisterInstance<TInterface>(aInstance,aName);
  269. end;
  270. function TIocContainer.RegisterOptions<T>(aOptions: TOptions): TIocRegistration<T>;
  271. begin
  272. Result := fRegistrator.RegisterOptions<T>(aOptions).AsSingleton;
  273. end;
  274. function TIocContainer.Resolve(aServiceType: PTypeInfo; const aName: string): TValue;
  275. begin
  276. Result := fResolver.Resolve(aServiceType,aName);
  277. end;
  278. function TIocContainer.Resolve<T>(const aName : string = ''): T;
  279. begin
  280. Result := fResolver.Resolve<T>(aName);
  281. end;
  282. { TIocRegistrator }
  283. constructor TIocRegistrator.Create;
  284. begin
  285. fDependencies := TDictionary<string,TIocRegistration>.Create;
  286. end;
  287. destructor TIocRegistrator.Destroy;
  288. var
  289. reg : TIocRegistration;
  290. begin
  291. for reg in fDependencies.Values do
  292. begin
  293. if reg <> nil then
  294. begin
  295. //free singleton instances not interfaced
  296. if (reg is TIocRegistrationInstance) and (TIocRegistrationInstance(reg).IsSingleton) then TIocRegistrationInstance(reg).Instance.Free;
  297. reg.Free;
  298. end;
  299. end;
  300. fDependencies.Free;
  301. inherited;
  302. end;
  303. function TIocRegistrator.GetKey(aPInfo : PTypeInfo; const aName : string = ''): string;
  304. begin
  305. {$IFDEF NEXTGEN}
  306. Result := aPInfo.Name.ToString;
  307. {$ELSE}
  308. Result := string(aPInfo.Name);
  309. {$ENDIF}
  310. if not aName.IsEmpty then Result := Result + '.' + aName.ToLower;
  311. end;
  312. function TIocRegistrator.IsRegistered<TInterface, TImplementation>(const aName: string): Boolean;
  313. var
  314. key : string;
  315. reg : TIocRegistration;
  316. begin
  317. Result := False;
  318. key := GetKey(TypeInfo(TInterface),aName);
  319. if fDependencies.TryGetValue(key,reg) then
  320. begin
  321. if reg.&Implementation = TImplementation then Result := True;
  322. end
  323. end;
  324. function TIocRegistrator.IsRegistered<TInterface>(const aName: string): Boolean;
  325. var
  326. key : string;
  327. reg : TIocRegistration;
  328. begin
  329. Result := False;
  330. key := GetKey(TypeInfo(TInterface),aName);
  331. if fDependencies.TryGetValue(key,reg) then
  332. begin
  333. if (reg is TIocRegistrationInterface) and (TIocRegistrationInterface(reg).Instance <> nil) then Result := True;
  334. end
  335. end;
  336. function TIocRegistrator.RegisterInstance<T>(const aName: string): TIocRegistration<T>;
  337. var
  338. reg : TIocRegistration;
  339. begin
  340. reg := RegisterInstance(TypeInfo(T),aName);
  341. Result := TIocRegistration<T>.Create(reg);
  342. end;
  343. function TIocRegistrator.RegisterInstance<TInterface>(aInstance: TInterface; const aName: string): TIocRegistration;
  344. var
  345. key : string;
  346. tpinfo : PTypeInfo;
  347. begin
  348. tpinfo := TypeInfo(TInterface);
  349. key := GetKey(tpinfo,aName);
  350. if fDependencies.TryGetValue(key,Result) then
  351. begin
  352. if Result.&Implementation = tpinfo.TypeData.ClassType then raise EIocRegisterError.Create('Implementation is already registered!');
  353. end
  354. else
  355. begin
  356. Result := TIocRegistrationInterface.Create;
  357. Result.IntfInfo := tpinfo;
  358. TIocRegistrationInterface(Result).Instance := aInstance;
  359. //reg.Instance := T.Create;
  360. fDependencies.Add(key,Result);
  361. end;
  362. end;
  363. function TIocRegistrator.RegisterInstance(aTypeInfo : PTypeInfo; const aName : string = '') : TIocRegistration;
  364. var
  365. key : string;
  366. begin
  367. key := GetKey(aTypeInfo,aName);
  368. if fDependencies.TryGetValue(key,Result) then
  369. begin
  370. if Result.&Implementation = aTypeInfo.TypeData.ClassType then raise EIocRegisterError.Create('Implementation is already registered!');
  371. end
  372. else
  373. begin
  374. Result := TIocRegistrationInstance.Create;
  375. Result.IntfInfo := aTypeInfo;
  376. Result.&Implementation := aTypeInfo.TypeData.ClassType;
  377. //reg.Instance := T.Create;
  378. fDependencies.Add(key,Result);
  379. end;
  380. end;
  381. function TIocRegistrator.RegisterOptions<T>(aOptions: T): TIocRegistration<T>;
  382. var
  383. pInfo : PTypeInfo;
  384. key : string;
  385. reg : TIocRegistration;
  386. begin
  387. pInfo := TypeInfo(IOptions<T>);
  388. key := GetKey(pInfo,'');
  389. if fDependencies.TryGetValue(key,reg) then
  390. begin
  391. if reg.&Implementation = aOptions.ClassType then raise EIocRegisterError.Create('Implementation for this interface is already registered!');
  392. end
  393. else
  394. begin
  395. reg := TIocRegistrationInterface.Create;
  396. reg.IntfInfo := pInfo;
  397. reg.&Implementation := aOptions.ClassType;
  398. TIocRegistrationInterface(reg).Instance := TOptionValue<T>.Create(aOptions);
  399. fDependencies.Add(key,reg);
  400. end;
  401. Result := TIocRegistration<T>.Create(reg);
  402. end;
  403. function TIocRegistrator.RegisterType<TInterface, TImplementation>(const aName: string): TIocRegistration<TImplementation>;
  404. var
  405. reg : TIocRegistration;
  406. begin
  407. reg := RegisterType(TypeInfo(TInterface),TImplementation,aName);
  408. Result := TIocRegistration<TImplementation>.Create(reg);
  409. end;
  410. function TIocRegistrator.RegisterType(aTypeInfo : PTypeInfo; aImplementation : TClass; const aName : string = '') : TIocRegistration;
  411. var
  412. key : string;
  413. begin
  414. key := GetKey(aTypeInfo,aName);
  415. if fDependencies.TryGetValue(key,Result) then
  416. begin
  417. if Result.&Implementation = aImplementation then raise EIocRegisterError.Create('Implementation for this interface is already registered!');
  418. end
  419. else
  420. begin
  421. Result := TIocRegistrationInterface.Create;
  422. Result.IntfInfo := aTypeInfo;
  423. Result.&Implementation := aImplementation;
  424. fDependencies.Add(key,Result);
  425. end;
  426. end;
  427. { TIocResolver }
  428. constructor TIocResolver.Create(aRegistrator : TIocRegistrator; aInjector : TIocInjector);
  429. begin
  430. fRegistrator := aRegistrator;
  431. fInjector := aInjector;
  432. end;
  433. function TIocResolver.CreateInstance(aClass: TClass): TValue;
  434. var
  435. ctx : TRttiContext;
  436. rtype : TRttiType;
  437. rmethod : TRttiMethod;
  438. rParam : TRttiParameter;
  439. value : TValue;
  440. values : TArray<TValue>;
  441. begin
  442. Result := nil;
  443. ctx := TRttiContext.Create;
  444. try
  445. rtype := ctx.GetType(aClass);
  446. if rtype = nil then Exit;
  447. for rmethod in TRttiInstanceType(rtype).GetMethods do
  448. begin
  449. if rmethod.IsConstructor then
  450. begin
  451. //if create don't have parameters
  452. if Length(rmethod.GetParameters) = 0 then
  453. begin
  454. Result := rmethod.Invoke(TRttiInstanceType(rtype).MetaclassType,[]);
  455. Break;
  456. end
  457. else
  458. begin
  459. for rParam in rmethod.GetParameters do
  460. begin
  461. value := Resolve(rParam.ParamType.Handle);
  462. values := values + [value];
  463. end;
  464. Result := rmethod.Invoke(TRttiInstanceType(rtype).MetaclassType,values);
  465. Break;
  466. end;
  467. end;
  468. end;
  469. finally
  470. ctx.Free;
  471. end;
  472. end;
  473. function TIocResolver.Resolve(aServiceType: PTypeInfo; const aName : string = ''): TValue;
  474. var
  475. key : string;
  476. reg : TIocRegistration;
  477. intf : IInterface;
  478. begin
  479. Result := nil;
  480. reg := nil;
  481. key := fRegistrator.GetKey(aServiceType,aName);
  482. if not fRegistrator.Dependencies.TryGetValue(key,reg) then raise EIocResolverError.CreateFmt('Type "%s" not register for IOC!',[aServiceType.Name]);
  483. //if is singleton return already instance if exists
  484. if reg.IsSingleton then
  485. begin
  486. if reg is TIocRegistrationInterface then
  487. begin
  488. if TIocRegistrationInterface(reg).Instance <> nil then
  489. begin
  490. if TIocRegistrationInterface(reg).Instance.QueryInterface(GetTypeData(aServiceType).Guid,intf) <> 0 then raise EIocResolverError.CreateFmt('Implementation for "%s" not registered!',[aServiceType.Name]);
  491. TValue.Make(@intf,aServiceType,Result);
  492. Exit;
  493. end;
  494. end
  495. else
  496. begin
  497. if TIocRegistrationInstance(reg).Instance <> nil then
  498. begin
  499. Result := TIocRegistrationInstance(reg).Instance;
  500. Exit;
  501. end;
  502. end;
  503. end;
  504. //instance not created yet
  505. if reg.&Implementation = nil then raise EIocResolverError.CreateFmt('Implemention for "%s" not defined!',[aServiceType.Name]);
  506. //use activator if assigned
  507. if reg is TIocRegistrationInterface then
  508. begin
  509. if Assigned(reg.ActivatorDelegate) then TIocRegistrationInterface(reg).Instance := reg.ActivatorDelegate().AsInterface
  510. else TIocRegistrationInterface(reg).Instance := CreateInstance(reg.&Implementation).AsInterface;
  511. if (TIocRegistrationInterface(reg).Instance = nil) or (TIocRegistrationInterface(reg).Instance.QueryInterface(GetTypeData(aServiceType).Guid,intf) <> 0) then raise EIocResolverError.CreateFmt('Implementation for "%s" not registered!',[aServiceType.Name]);
  512. TValue.Make(@intf,aServiceType,Result);
  513. end
  514. else
  515. begin
  516. if Assigned(reg.ActivatorDelegate) then TIocRegistrationInstance(reg).Instance := reg.ActivatorDelegate().AsObject
  517. else
  518. begin
  519. TIocRegistrationInstance(reg).Instance := CreateInstance(reg.&Implementation).AsObject;
  520. end;
  521. Result := TIocRegistrationInstance(reg).Instance;
  522. end;
  523. end;
  524. function TIocResolver.Resolve<T>(const aName : string = ''): T;
  525. var
  526. pInfo : PTypeInfo;
  527. begin
  528. Result := Default(T);
  529. pInfo := TypeInfo(T);
  530. Result := Resolve(pInfo,aName).AsType<T>;
  531. end;
  532. { TIocRegistration<T> }
  533. function TIocRegistration<T>.AsScoped: TIocRegistration<T>;
  534. begin
  535. Result := Self;
  536. fRegistration.AsScoped;
  537. end;
  538. function TIocRegistration<T>.AsSingleton: TIocRegistration<T>;
  539. begin
  540. Result := Self;
  541. fRegistration.AsSingleton;
  542. end;
  543. function TIocRegistration<T>.AsTransient: TIocRegistration<T>;
  544. begin
  545. Result := Self;
  546. fRegistration.AsTransient;
  547. end;
  548. constructor TIocRegistration<T>.Create(aRegistration: TIocRegistration);
  549. begin
  550. fRegistration := aRegistration;
  551. end;
  552. function TIocRegistration<T>.DelegateTo(aDelegate: TActivatorDelegate<T>): TIocRegistration<T>;
  553. begin
  554. Result := Self;
  555. fRegistration.ActivatorDelegate := function: TValue
  556. begin
  557. Result := TValue.From<T>(aDelegate);
  558. end;
  559. end;
  560. end.