正如我已经在评论中写的那样,我认为在这种情况下,使用一个主要服务(主类,单例)是一个好主意,它可以让您访问其他服务。您的所有模块都有唯一的 ID ( TGUID
)。在程序执行开始时,他们应该在主服务中注册自己。
例如。主要服务单位:
unit AppServices;
interface
uses generics.collections, rtti;
type
// Unique ID Attribute for services
ServiceIDAttribute = class(TCustomAttribute)
strict private
FId : TGUID;
public
constructor Create(ServiceID: string);
property ID : TGUID read FId;
end;
//Services Base class
TCustomAppService = class(TObject)
strict protected
public
end;
// Main Service Object
TAppServices = class(TObject)
strict private
class var
FServices : TObjectDictionary<TGUID, TCustomAppService>;
var
public
class constructor Create();
class destructor Destroy();
class procedure RegisterService(aService : TCustomAppService);
class function QueryService(ServiceID : TGUID):TCustomAppService;
end;
这里class constructor
&destructor
简单地创建和释放 FServices
字典。QueryService
方法通过其唯一 ID 返回 Service:
class function TAppServices.QueryService(ServiceID: TGUID): TCustomAppService;
begin
result := nil;
if FServices.ContainsKey(ServiceID) then
result := FServices[ServiceID];
end;
方法从参数的类名RegisterService
中提取RTTI
Attribute ( ServciceIDAttribute
) 并将这一对 (id-service) 添加到字典中:
class procedure TAppServices.RegisterService(aService: TCustomAppService);
var ctx : TRttiContext;
st : TRttiType;
a : TCustomAttribute;
id : TGUID;
begin
ctx := TRttiContext.Create();
try
st := ctx.GetType(aService.ClassType);
for a in st.GetAttributes() do begin
if not (a is ServiceIDAttribute) then
continue;
id := ServiceIDAttribute(a).ID;
FServices.AddOrSetValue(id, aService);
break;
end;
finally
ctx.Free();
end;
end;
现在,关于终端服务。例如 UserManager 单元:
unit UserManager;
interface
uses AppServices;
const
SID_UserManager : TGUID = '{D94C9E3A-E645-4749-AB15-02631F21EC4E}';
type
[ServiceID('{D94C9E3A-E645-4749-AB15-02631F21EC4E}')]
TUserManager = class(TCustomAppService)
strict private
FActiveUserName: string;
public
property ActiveUserName: string read FActiveUserName;
end;
implementation
initialization
TAppServices.RegisterService(TUserManager.Create());
end.
现在我们可以测试我们的代码:
procedure TestApp();
var uMgr :TUserManager;
dbMgr : TDBmanager;
begin
dbMgr := TAppServices.QueryService(SID_DBManager) as TDBManager;
if dbMgr.Connected then
writeln('connected!')
else writeln('not connected');
uMgr := TAppServices.QueryService(SID_UserManager) as TUserManager;
writeln('Active user: ', uMgr.ActiveUserName);
end;
摘要:
TAppServices
是主要对象,提供对 App 中任何服务的访问。它对终端服务一无所知,因此它没有依赖关系。您可以根据需要更改其实现。您可以根据需要拥有尽可能多的 TCustomAppService 类后代。向应用程序添加新服务时,不应更改TAppServices
类接口或实现。