我想将接口注入对象,但找不到属性[Inject]的问题
怎么了
unit uStorage;
interface
uses
uStorageInterface;
type
TStorageService = class (TInterfacedObject, IStorageService)
private
FPath: String;
procedure SetPath(const Value: String);
function GetPath: String;
public
property Path: String read GetPath write SetPath;
end;
implementation
{ TStorageService }
function TStorageService.GetPath: String;
begin
Result:= FPath;
end;
procedure TStorageService.SetPath(const Value: String);
begin
FPath := Value;
end;
unit uStorageInterface;
interface
type
IStorageService = interface
['{F1B4C339-BE8E-4182-A191-95266160FA6E}']
procedure SetPath(const Value: String);
function GetPath: String;
property Path: String read GetPath write SetPath;
end;
IStorageObject = interface
['{7B97B659-EDF3-4892-AFAB-985487660372}']
end;
implementation
end.
unit uObjects;
interface
uses
Vcl.StdCtrls,
System.Classes,
uStorageInterface,
Spring.Container,
Spring.Services,
Spring.Container.Common;
type
TMyButton= class (TButton, IStorageObject)
private
FStorage: IStorageService;
function GetStorage: IStorageService;
protected
procedure DoExit; override;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
{ TMyButton }
constructor TMyButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FStorage:= ServiceLocator.GetService<IStorageService>;
end;
procedure TMyButton.DoExit;
begin
inherited;
if assigned(FStorage) then
begin
self.Caption:= FStorage.Path;
end;
end;
function TMyButton.GetStorage: IStorageService;
begin
Result:= FStorage;
end;
end.
unit Unit2;
interface
uses
System.SysUtils, System.Classes,
Vcl.Dialogs;
type
TDataModule2 = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
DataModule2: TDataModule2;
implementation
uses
uStorage,
uObjects,
uStorageInterface,
Spring.Services,
Spring.Container;
{%CLASSGROUP 'Vcl.Controls.TControl'}
{$R *.dfm}
procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
GlobalContainer.RegisterType<TStorageService>.Implements<IStorageService>.DelegateTo(
function: TStorageService
begin
Result := TStorageService.Create();
Result.Path:= 'MyButton';
end).AsSingleton;
GlobalContainer.Build;
end;
end.
在构造函数TMyButton.Create(AOwner:TComponent)中,我想用字段注入替换ServiceLocator,但是找不到如何执行此操作。
一些例子,但是不起作用。我看不到问题。
unit uObjects;
interface
uses
Vcl.StdCtrls,
System.Classes,
uStorageInterface,
Spring.Container,
Spring.Services,
Spring.Container.Common;
type
TMyButton= class (TButton, IStorageObject)
private
[Inject]
FStorage: IStorageService;
function GetStorage: IStorageService;
protected
procedure DoExit; override;
public
constructor Create(AOwner: TComponent); override;
end;
implementation
{ TMyButton }
constructor TMyButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//FStorage:= ServiceLocator.GetService<IStorageService>;
end;
procedure TMyButton.DoExit;
begin
inherited;
if assigned(FStorage) then
begin
self.Caption:= FStorage.Path;
end;
end;
function TMyButton.GetStorage: IStorageService;
begin
Result:= FStorage;
end;
end.
procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
GlobalContainer.RegisterType<TStorageService>.Implements<IStorageService>.DelegateTo(
function: TStorageService
begin
Result := TStorageService.Create();
Result.Path:= 'MyButton';
end).AsSingleton;
GlobalContainer.RegisterType<TMyButton>.Implements<IStorageObject>.InjectField('FStorage');
GlobalContainer.Build;
end;
当我在运行时创建TMyButton时,TMyButton中的FStorage为零。
当我使用FStorage:= ServiceLocator.GetService;在构造函数中,然后分配FStorage。但是我想使用注入而不是ServiceLocator。如果可能的话。
最佳答案
首先TMyButton
的注册错误。容器本身不会为AOwner填充nil。这意味着它将退回到TObject构造函数,而将按钮实例初始化为一半。
使用子依赖解析器为TComponent ctor进行此操作,或以这种方式显式注册。
GlobalContainer.RegisterType<TMyButton>.Implements<IStorageObject>
.DelegateTo(
function: TMyButton
begin
Result := TMyButton.Create(nil);
end)
.InjectField('FStorage');
现在注意!如果您将其解析为TMyButton,则容器将不知道如何解决该问题,因为您将IStorageObject指定为服务类型。如果指定服务类型,则除非明确定义,否则容器不会解析该类。
但是,这里有一个小故障,因为无论何时解析它,容器都会尝试再次注册该类。这导致TMyButton的第二次注册,但未指定字段注入。我会解决的。
在此之前,您可以通过在注册中添加
Implements<TMyButton>
来解决此问题。关于delphi - 如何将现场接口(interface)注入(inject)对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30345602/