我在使用 Spring4D 框架的 GlobalContainer 创建从另一个继承的自定义类对象时遇到问题。
父类:
type
TVSPSection = class ( TInterfacedObject, IVSPSection )
private
_id : Integer;
_organization : IDirectoryObject;
function GetId () : Integer;
procedure SetId ( const value : Integer );
function GetOrganization () : IDirectoryObject;
procedure SetOrganization ( const value : IDirectoryObject );
public
property Id : Integer read GetId write SetId;
property Organization : IDirectoryObject read GetOrganization write SetOrganization;
end;
...
initialization
GlobalContainer.RegisterType<TVSPSection>.Implements<IVSPSection>.
InjectField ( '_organization' )
;
后代类:
type
TVSPSeismicSection = class ( TVSPSection, IVSPSeismicSection, IInterface )
private
_report : IReport;
function GetReport () : IReport;
procedure SetReport ( const value : IReport );
public
property Report : IReport read GetReport write SetReport;
end;
...
initialization
GlobalContainer.RegisterType<TVSPSeismicSection>.Implements<IVSPSeismicSection>.
InjectField ( '_report' )
;
end.
我尝试创建 TVSPSeismicSection 对象:
_seismicSection : IVSPSeismicSection;
_seismicSection := GlobalContainer.Resolve<IVSPSeismicSection>;
接下来,我尝试访问(父类的)“组织”字段并收到访问冲突错误。
_seismicSection.Organization.Id := -1; <- exception is here
那么,问题是如何告诉父类使用 GlobalContainer 解析器启动它的字段?也许可以通过 DelegateTo 方法,但是如何实现呢?
我发现的一种方法是在后代类的构造函数中启动父字段,如下所示:
constructor TVSPSeismicSection.Create ();
begin
Organization := GlobalContainer.Resolve<IDirectoryObject>;
end;
但这违反了依赖注入(inject)范例,因为我必须将附加类 (IDirectoryObject) 包含到后代类中。
最佳答案
有多种方法,具体取决于哪一种是最好的。 通常,必需的依赖项应作为构造函数参数传递,而可选的依赖项应通过属性注入(inject)传递。
因此,如果您向 TVSPSection
类添加一个采用 IDirectoryObject
参数的构造函数,则容器能够满足该参数(如果它知道如何解析 IDirectoryObject
.
这通常是最简洁的方法,因为使用 DI 容器的一条规则是编写与 DI 容器无关的代码,并将容器仅用作工具而不是依赖项。
如果您想保留属性注入(inject),那么在该属性上使用 Inject
属性应该可以工作(不要忘记将 Spring.Container.Common
添加到用于该属性)就像在注册中指定 InjectProperty 一样(虽然我可能会避免字段注入(inject),因为这只能通过 RTTI 而不是常规代码来实现 - 请参阅上一段)。
关于delphi - 如何在Delphi中使用GlobalContainer(Spring4D框架)创建继承对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29385988/