Delphi依赖注入:框架与委托构造器

时间:2011-05-10 04:05:59

标签: delphi dependency-injection inversion-of-control ioc-container freepascal

当您可以简单地使用以下模式时,为什么要使用依赖注入框架?

unit uSomeServiceIntf;

interface

type
  ISomeService = interface
    procedure SomeMethod;
  end;

var
  CreateSomeService: function: ISomeService;

implementation

end.

unit uSomeServiceImpl;

interface

type 
  TSomeService = class(TInterfacedObject, ISomeService)
    procedure DoSomething;
  end;

function CreateSomeService: ISomeService;

implementation 

function CreateSomeService: ISomeService;
begin
  Result := TSomeService.Create;
end;

procedure TSomeService.DoSomeThing;
begin
  ...
end;

end.

unit uInitializeSystem;

interface

procedure Initialze;

implementation

uses
  uSomeServiceIntf,
  uSomeServiceImpl;

procedure Initialze;
begin
  uSomeServiceIntf.CreateSomeService := uSomeServiceImpl.CreateSomeService;
end;

end.

我试图掌握使用框架而不是这样做的好处,但到目前为止我只看到了这种简单方法的好处:

1)参数化构造函数更容易实现。例如。:     VAR       CreateSomeOtherService:function(aValue:string);

2)更快(在容器中无需查找)

3)更简单

我将如何使用它:

unit uBusiness;
interface
[...]
implementation

uses 
  uSomeServiceIntf;
[...]
procedure TMyBusinessClass.DoSomething;
var
  someService: ISomeService;
begin
  someService := CreateSomeService;
  someService.SomeMethod;
end;

end.

您使用DI框架而不是这种方法的理由是什么?

使用DI框架看起来如何?

据我所知,如果你使用DI框架而不是在界面上注册具体类,那么系统的消费者会询问给定框架的实现。 所以会有一个注册电话:

DIFramework.Register(ISomeInterface, TSomeInterface)

当您需要ISomeInterface实现时,您可以向DI框架询问它:

var
  someInterface: ISomeInterface;
begin
  someInteface := DIFrameWork.Get(ISomeInterface) as ISomeInterface;

现在很明显,如果你确实需要传递参数来创建一个ISomeInterface,那么使用DIFramework就会变得更复杂(但是使用上述方法很简单)。

1 个答案:

答案 0 :(得分:6)

在您的情况下,您必须在设计时提前知道工厂函数ptr(var CreateSomeService)的名称。当然,接口和函数ptr在同一个Delphi单元文件中耦合在一起,但这只是一个Delphi遗物,全局变量不是线程安全的,不受访问保护。

如果你在运行时有一个接口,作为一些函数或从配置文件中读取的结果 - 你不知道调用什么工厂函数来获取实现者的实际实例。

DIFrameWork.Get(ISomeInterface) as ISomeInterface隐藏了您的工厂功能,因此您只需要接口,而不是接口工厂功能。如果您试图隐藏工厂功能,那么您还必须隐藏参数。 (最终会得到类似于DI框架的东西)。