Para un problema particular en la arquitectura de una aplicación en la que estoy trabajando, las interfaces parecen ser una buena solución. Específicamente, algunos "objetos comerciales" dependen de una serie de configuraciones que se extraen de la base de datos en la aplicación real. Dejar que los objetos de negocio piden una interfaz (a través Inversión de Control), y dejando un TDatabaseSettings
objeto central implementar esas interfaces, permite un mejor aislamiento, y por lo tanto para las pruebas unitarias mucho más fácil.Anulación (deshabilitación) Conteo de referencias de Delphi para las interfaces
Sin embargo, en Delphi, las interfaces parecen venir con una, en este caso, la prima desagradable: el recuento de referencias. Esto significa que si hago algo como esto:
type
IMySettings = interface
function getMySetting: String;
end;
TDatabaseSettings = class(..., IMySettings)
//...
end;
TMyBusinessObject = class(TInterfacedObject, IMySettings)
property Settings: IMySettings read FSettings write FSettings;
end;
var
DatabaseSettings: TDatabaseSettings;
// global object (normally placed in a controller somewhere)
//Now, in some function...
O := TMyBusinessObject.Create;
O.Settings := DatabaseSettings;
// ... do something with O
O.Free;
En la última línea (O.Free
), mi DatabaseSettings
objeto global es ahora también liberado, ya que se pierde la última referencia de la interfaz a la misma (que estaba contenido en O
) !
Una solución sería la de almacenar la DatabaseSettings
objeto 'global' con una interfaz; Otra solución sería anular el mecanismo de recuento de referencias para la clase TDatabaseSettings
, por lo que puedo continuar administrando el DatabaseSettings
como un objeto normal (que es mucho más consistente con el resto de la aplicación).
Así que, en resumen, mi pregunta es: ¿cómo desactivo el mecanismo de conteo de referencia de la interfaz para una clase en particular?
he sido capaz de encontrar algo de información que sugiera anulando los métodos IInterface
_AddRef
y _Release
para la clase (TDatabaseSettings
en el ejemplo); ¿Alguien ha hecho eso alguna vez?
O habría que decir que no debería hacer esto (confundiendo? Sólo una mala idea?), Y encontrar una solución diferente al problema de arquitectura?
¡Muchas gracias!
Muchas gracias por la extensa respuesta, ¡es muy apreciada! Sí, probablemente debería pensar un poco más antes de ir por el camino oscuro de deshabilitar el conteo de referencias. – onnodb
Ok, lo probé en D2009 y funcionó a las mil maravillas ;-). –
¿Tengo razón en que su ejemplo no deshabilita completamente el recuento de referencias, sino que hace que el recuento de referencias comience en 1? Supongo que también podrías lograr eso llamando explícitamente a "TMyInterfacedObject._AddRef" justo después de la creación del objeto, y luego haciendo un "_Release" donde normalmente llamarías "Gratis". – onnodb