11

¿Por qué usaría un Marco de inyección de dependencia cuando puede usar simplemente el siguiente patrón?Delphi Dependency Injection: Framework vs Delegating Constructor

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. 

Estoy tratando de captar los beneficios de utilizar un marco en lugar de hacer esto, pero hasta ahora sólo ver los beneficios de este enfoque simple:

1) Los constructores parametrizados son más fáciles de implementar. P. ej .: var CreateSomeOtherService: function (aValue: string);

2) más rápido (no hay operaciones de búsqueda necesarias en un recipiente)

3) simplier

éste es cómo lo usaría:

unit uBusiness; 
interface 
[...] 
implementation 

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

end. 

¿Cuál sería su razonamiento para utilizar un DI marco en lugar de este enfoque?

¿Cómo se vería esto con un marco DI?

Por lo que sé si usaría un marco DI, registraría la clase concreta contra la interfaz y los consumidores del sistema solicitarían una implementación para el marco dado. Así habría una llamada de registro:

DIFramework.Register(ISomeInterface, TSomeInterface) 

y cuando se necesita una implementación ISomeInterface le puede pedir al marco DI para ello:

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

Ahora, evidentemente, si necesita pasar parámetros para crear un ISomeInterface todo se complica con el DIFramework (pero simple con el enfoque descrito anteriormente).

+0

¿Quizás podría agregar un ejemplo de código fuente usando un contenedor DI para aclarar las diferencias en la declaración y el uso? – mjn

+0

¿No estás seguro de lo que quieres decir con "conveniencia" ?. ¿Influencia? –

+0

@Warren, tal vez el OP quiere saber las razones para elegir ya sea el patrón exeplified o el contenedor DI ... –

Respuesta

6

En su caso, debe conocer el nombre de la función de fábrica ptr (var CreateSomeService) de antemano, en el momento del diseño. Claro, la interfaz y la función ptr están acopladas juntas en el mismo archivo de unidad Delphi, pero eso es solo una reliquia Delphi, la var global no es segura para hilos y no está protegida contra acceso.

Y si tiene una interfaz en tiempo de ejecución, como resultado de alguna función o una lectura de un archivo de configuración, no sabe a qué función de fábrica llamar para obtener la instancia real de un implementador.

DIFrameWork.Get(ISomeInterface) as ISomeInterface le oculta la función de fábrica por lo que solo necesita la interfaz, no tanto la interfaz y la función de fábrica. Si intenta ocultar la función de fábrica, también deberá ocultar los parámetros. (y terminaría con algo muy parecido a ese marco DI).

Cuestiones relacionadas