Delphi Spring DI:是否可以在没有实现类型的情况下委托接口实例化?

Oli*_*sen 7 delphi com dependency-injection ioc-container spring4d

我刚刚开始使用Delphi Spring Framework,并想知道当前版本的DI容器是否允许将构造委托给工厂方法而不指定实现类型?

例如类似的东西:

GlobalContainer
  .RegisterFactory<ISomeObject>(
    function: ISomeObject 
    begin 
      Result := CreateComObject(CLASS_SomeObject) as ISomeObject; 
    end)
  .Implements<ISomeObject>  // could probably be implied from the above
  .AsSingletonPerThread;
Run Code Online (Sandbox Code Playgroud)

如您所见,我的具体用例是COM对象的实例化.在这种情况下,实现我感兴趣的接口的类不是我的应用程序的一部分,但我仍然可以通过调用CreateComObject/ 来创建实例CoCreateInstance.但是,似乎我运气不好,因为Container中的注册似乎总是绑定到实际的实现类.

假设目前不可能这样做,那么你们的专家怎么解决这个问题呢?你会创建一个包装类或虚拟类,或者你只是将COM对象保留在DI容器之外并简单地通过它实例化它们CreateComObject

Ste*_*nke 8

不幸的是,弹簧DI容器的当前设计不允许这样做.它内部假定每种服务类型(通常是接口,但也可以是类)由组件类型(类)实现.因此,在这种情况下TObject我们需要的几个地方IInterface.与传递给DelegateTo方法的委托一样,返回组件类型(或非泛型情况下的TObject)而不是服务类型.

这也是因为您可以在一个流畅的接口调用中注册一个具有多个接口实现的组件类型.喜欢:

GlobalContainer
  .RegisterType<TMyObject>
  .Implements<IMyInterface>
  .Implements<IMyOtherInterface>;
Run Code Online (Sandbox Code Playgroud)

容器现在检查是否TMyObjectIMyInterface和兼容IMyOtherInterface.当调用Resolve服务解析器GetInterface在实例上使用以获取请求的接口引用时.超出该点的所有内容都是在对象引用上完成的.

由于我有一些DI容器的计划,在注册接口时不需要依赖于实现类,因此将来会解决此问题,但不会很快解决.

更新(08.11.2012):

从r522开始,可以通过以下方式注册接口类型:

GlobalContainer
  .RegisterType<ISomeObject>
  .DelegateTo(
    function: ISomeObject 
    begin 
      Result := CreateComObject(CLASS_SomeObject) as ISomeObject; 
    end)
  .AsSingletonPerThread;
Run Code Online (Sandbox Code Playgroud)

在此示例中,它将注册ISomeObject为服务以及具有其继承的GUID的任何接口.

此外,您可以通过调用添加其他接口,Implements<T>但与类不同,如果构造的实例实际上真的支持该接口,则在注册时将不会进行验证,因为它根本不可能.目前,您nilResolve<T>使用不受支持的服务类型进行呼叫时会收到.它可能在将来引发例外.

  • 感谢更新!太精彩了!:) (3认同)