ICommand = interface TCommand = class(TInterfacedobject,ICommand) IVecadCommand = interface(ICommand) TVecadCommand = class(TCommand,IVecadCommand) TVecadCommandJPG = class(TVecadCommand,IVecadCommand) TCommandDeckelJPG = class(TVecadCommandJPG,IVecadCommand)
GlobalContainer.RegisterComponent<TCommandDeckelJPG>.Implements<IVecadCommand>('deckel_jpg');
然后我尝试在ServiceLocator的帮助下创建一个对象:
var i: Integer; com: ICommand; begin Result := nil; com := ServiceLocator.GetService<ICommand>(actionName); com.setSession(designSession); Result := com; end;
Invalid class typecast
为了避免异常,我这样做:
var i: Integer; com: IVecadCommand; begin Result := nil; com := ServiceLocator.GetService<IVecadCommand>(actionName); com.setSession(designSession); Result := com; end;
一切都好.
要点是我必须在这种情况下使用TContainer作为TCommand的Repository和继承的类.所以我必须先使用ServiceLocator.
我该怎么做才能避免异常并在TContainer中使用ICommand而不是IVecadCommand?
谢谢.将愉快地提供额外的细节.
解决方法
该错误具有误导性,实际上它应该引发一个异常,告诉你它不知道如何解决(似乎是一个错误 – 我会调查).
那是因为您只能要求明确注册的服务.它不会查找继承链.
如果您希望能够以ICommand的身份解决您的课程,则需要添加另一个.Implements< ICommand>注册.由于名称必须是唯一的,并且您可能希望按名称解析,因此必须为其指定与IVecadCommand不同的名称.如果您永远不想将其解析为IVecadCommand(您可以在解析为ICommand后使用支持),那么只需将现有注册从IVecadCommand更改为ICommand即可.
编辑:
我实际上并不完全正确 – 当您按名称解析时,容器不会检查传递的类型.在这种情况下的问题是将IVecadCommand转换为ICommand,其由TValue.AsType< T>完成.但它没有正确处理.我将在即将发布的版本中解决这个问题.我只是不知道怎么样.为了保持一致性,这里的类型也应该严格.无论如何,如果你做了我上面所说的解决问题,你现在就安全了.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。