我刚开始使用Delphi的Spring框架,并想知道的DI容器的当前版本是否在某种程度上允许委托建设,不指定一个执行型工厂方法?
例如,一些与此类似:
GlobalContainer
.RegisterFactory<ISomeObject>(
function: ISomeObject
begin
Result := CreateComObject(CLASS_SomeObject) as ISomeObject;
end)
.Implements<ISomeObject> // could probably be implied from the above
.AsSingletonPerThread;
正如你所看到的,我的具体使用情况是COM对象的实例。 在这种情况下,实现我感兴趣的接口的类是不是我的应用程序的一部分,但我仍然可以通过调用创建实例CreateComObject
/ CoCreateInstance
。 但是,看来我的运气在集装箱登记总是出现被绑定到一个实际的实现类。
假设这是不可能的,因为这样的时刻,你会怎么专家在那里解决这个问题? 你会创建一个包装类或伪类或将你只是保持COM对象出了DI容器的,只是通过实例化它们CreateComObject
?
不幸的是,春天DI容器的当前设计不允许。 它在内部假定每个服务类型(通常为接口,但也可以是一个类)是由一个部件类型(类)来实现。 于是,具有TObject
几个地方,我们需要IInterface
在这种情况下。 像你传递给DelegateTo方法委托返回(在非一般的情况下,或TObject的)组件类型,而不是服务类型。
这也是因为你可以注册在短短一个流畅的接口调用多个接口实现一个组件类型。 喜欢:
GlobalContainer
.RegisterType<TMyObject>
.Implements<IMyInterface>
.Implements<IMyOtherInterface>;
现在容器检查,如果TMyObject
是兼容IMyInterface
和IMyOtherInterface
。 当调用Resolve
服务解析器使用GetInterface
的实例来获得所请求的接口引用。 一切都超出该点上的对象引用来完成。
因为我有那些要求没有登记时,接口这个问题将在未来很快解决,但不是在实现类的依赖的DI容器一些计划。
更新(2012年8月11日):
由于R522可以通过以下方式注册接口类型:
GlobalContainer
.RegisterType<ISomeObject>
.DelegateTo(
function: ISomeObject
begin
Result := CreateComObject(CLASS_SomeObject) as ISomeObject;
end)
.AsSingletonPerThread;
在这个例子中,将寄存器ISomeObject
作为服务并用它从继承的GUID任何接口。
另外,您还可以通过调用添加其他接口Implements<T>
但不同的类会有在注册时不进行验证,如果构建的实例居然真的支持接口,因为它根本是不可能的。 目前,您将获得nil
打电话时Resolve<T>
与非支持的服务类型。 它可以提高在未来的一个例外。
看起来并不像Spring框架的架构目前支持它,但它肯定是可行的。 有人提出了spring4d支持组中并没有对这个想法感兴趣。
有一个通用TFactory
类Spring.DesignPatterns
可能使用的包装CreateComObject/COCreateInstance
。
文章来源: Delphi Spring DI: Is it possible to delegate interface instantiation without an implementing type?