Delphi Dependency Injection: Framework vs Delegating Constructor

Почему вы используете платформу Injection Dependency, когда можете просто использовать следующий шаблон?

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) Параметризированные конструкторы легче реализовать. Например.:   вар     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

В вашем случае вы должны знать имя функции factory ptr (var CreateSomeService) заранее, во время разработки. Конечно, интерфейс и функция ptr связаны вместе в одном файле Unit Delphi, но это только релиз Delphi, глобальный var не является потокобезопасным, а не защищенным от доступа.

И что, если вы получили интерфейс во время выполнения, в результате некоторой функции или чтения из файла конфигурации - вы не знаете, какую функцию factory вызывать, чтобы получить фактический экземпляр разработчика.

DIFrameWork.Get(ISomeInterface) as ISomeInterface скрывает от вас функцию factory, поэтому вам нужен только интерфейс, а не интерфейс и функция factory. Если вы попытаетесь скрыть функцию factory, вам также придется скрыть параметры. (и в итоге получится что-то похожее на эту инфраструктуру DI).