【问题标题】:Service location - check the project for implementation服务地点——检查项目执行情况
【发布时间】:2016-10-31 10:52:28
【问题描述】:
当项目使用服务定位器时,实现类会在定位器中注册。然后在某些地方的运行时要求定位器解决这样的某些服务(很多这些服务是单例的):
LSvc := Locator.Resolve<ISomeService>;
不好的是它是一种反模式。但是假设这种情况发生了,有没有办法通过像这样在定位器中注册类来检查是否有一个单元实现了 ISomeService?
Locator.Register<ISomeService>(TSomeService);
- 解析源文件;
- 具有称为“*.Dependencies.pas”的特殊单元,其中列出了所有实现单元。
在这种情况下还能做什么?
【问题讨论】:
标签:
delphi
dependency-injection
service-locator
【解决方案1】:
有可能使用 RTTI 信息找到此信息。所以下面的代码只适用于最新版本的 Delphi。
var
LIntf, LClass: TRttiType;
LImpl: TRttiInterfaceType;
LCtx: TRttiContext;
LFound: Boolean;
begin
LCtx := TRttiContext.Create;
for LIntf in LCtx.GetTypes do
if LIntf.TypeKind = tkInterface then
begin
LFound := False;
for LClass in LCtx.GetTypes do
begin
if LClass.TypeKind = tkClass then
for LImpl in TRttiInstanceType(LClass).GetImplementedInterfaces do
if LImpl.QualifiedName = LIntf.QualifiedName then
begin
LFound := True;
Break;
end;
if LFound then
Break;
end;
if not LFound then
Writeln(LIntf.QualifiedName, ' is not implemented by any class.');
end;
end;
您可以通过 QualifiedName 过滤接口和类型。该名称包含完整的单元名称作为类型的前缀。
因此,即使不应用过滤器,也可以将其输出保存到文本文件中,在过滤掉不需要的(非必需接口)后,您将能够找到在项目中编译的接口,但是有没有实现它们的类。
这正是服务在项目之间重用并通过服务定位器请求的情况。