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).