Инъекция зависимостей Delphi: Framework vs делегирование конструктора

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

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: функция (aValue: строка);

2) быстрее (без поиска необходимо в контейнере)

3) Simplier

вот как я бы его использовал:

unit uBusiness;
interface
[...]
implementation

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

end.

каковы были бы ваши рассуждения, чтобы использовать структуру DI вместо этого подхода?

как это будет выглядеть с помощью di framework?

насколько я знаю, если бы вы использовали структуру DI, чем вы зарегистрировали бы конкретный класс против интерфейса, а затем потребители системы попросили бы реализацию для данной структуры. Так есть будет регистрационный звонок:

DIFramework.Register(ISomeInterface, TSomeInterface)

и когда вам нужна реализация ISomeInterface, вы можете попросить di framework для этого:

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

теперь, очевидно, если вам нужно передать параметры для создания ISomeInterface, все становится сложнее с DIFramework (но просто с описанным выше подходом).

1 ответов


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

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

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