我正在嘗試創建一個最小的示例,它與 Spring4D[inject]屬性做同樣的事情。它應該自動決議 my TOrderAdapter.FDetailsAdapter,我想在Factory單元內手動實體化它(不像 Spring4D 容器那樣作業,首先從外部注冊介面)。該工廠應該伸手與所要求的任何所需的介面[inject]。
很明顯,我的代碼無法作業(TOrderAdapter.FDetailsAdapter沒有被注入,給了我一個nil指標 Access Violation on ButtonClick,第一次使用)。通過Spring4D源讀取,我無法看到這邏輯件是,我就是缺少了所需的功能,作業在我的例子。
program OrderDetails;
uses
Vcl.Forms,
Order.Adapter in 'Order.Adapter.pas',
Details in 'Details.pas',
Details.Adapter in 'Details.Adapter.pas',
Factory.Adapter in 'Factory.Adapter.pas',
Factory in 'Factory.pas',
Order in 'Order.pas',
Order.View in 'Order.View.pas' {OrderForm};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TOrderForm, OrderForm);
Factory.Adapter.Factory := TFactoryAdapter.Create;
Application.Run;
end.
unit Factory;
uses
Rtti, TypInfo;
type
InjectAttribute = class(TCustomAttribute)
private
fServiceType: PTypeInfo;
fValue: TValue;
public
constructor Create(ServiceType: PTypeInfo); overload;
property ServiceType: PTypeInfo read fServiceType;
property Value: TValue read fValue;
end;
implementation
constructor InjectAttribute.Create(ServiceType: PTypeInfo);
begin
inherited Create;
fServiceType := ServiceType;
end;
end.
unit Factory.Adapter;
uses
Details, Details.Adapter, Order, Order.Adapter;
type
TFactoryAdapter = class
private
FDetailsAdapter: IDetailsAdapter;
FOrderAdapter: IOrderAdapter;
public
constructor Create;
function Inject: IInterface; overload; // unused
end;
var
Factory: TFactoryAdapter;
implementation
constructor TFactoryAdapter.Create;
begin
FDetailsAdapter := TDetailsAdapter.Create;
FOrderAdapter := TOrderAdapter.Create;
end;
function TFactoryAdapter.Inject: IInterface; // unused
begin
Result := FDetailsAdapter;
end;
end.
unit Details.Adapter;
uses
Details, Winapi.Windows, SysUtils;
type
TDetailsAdapter = class(TInterfacedObject, IDetailsAdapter)
private
FID: Integer;
public
procedure SetID(AID: Integer);
function GetID: Integer;
published
property ID: Integer read GetID write SetID;
end;
implementation
procedure TDetailsAdapter.SetID(AID: Integer);
begin
FID := AID;
OutputDebugString(PWideChar('OrderDetail ID set to ' IntToStr(FID)));
end;
function TDetailsAdapter.GetID: Integer;
begin
Result := FID;
end;
end.
unit Order.Adapter;
uses
Order, Order.View, Details, Factory,
Vcl.Forms;
type
TOrderAdapter = class(TInterfacedObject, IOrderAdapter)
private
[inject]
FDetailsAdapter: IDetailsAdapter;
public
constructor Create;
procedure ButtonClick(Sender: TObject);
end;
var
OrderForm: TOrderForm;
implementation
constructor TOrderAdapter.Create;
begin
OrderForm.Button1.OnClick := ButtonClick;
end;
procedure TOrderAdapter.ButtonClick(Sender: TObject);
begin
FDetailsAdapter.ID := 5;
end;
end.
uj5u.com熱心網友回復:
容器使用 RTTI 來收集具有該屬性的成員并將正確的服務注入其中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/409136.html
標籤:
