sé que pregunta similar se le pidió varias veces (por ejemplo: here, here, here y) pero era para las versiones anteriores de la Unidad, donde la respuesta fue dependiente utilizada LifetimeManager
clase.Unidad 2.0 y gastos de tipos IDisposable (especialmente con PerThreadLifetimeManager)
Documentación dice:
Unidad utiliza tipos específicos que heredan de la clase base LifetimeManager (denominados colectivamente como vida manager) para controlar cómo se almacena referencias a instancias de objeto y cómo el contenedor dispone de estas instancias .
Ok, suena bien, así que decidí verificar la implementación de compilación en los administradores de por vida. Mi conclusión:
TransientLifetimeManager
- sin manejo de eliminación. Container solo resuelve la instancia y no la rastrea. El código de llamada es responsable de eliminar la instancia.ContainerControlledLifetimeManager
- descarta la instancia cuando se elimina el administrador de por vida (= cuando el contenedor está dispuesto). Proporciona una instancia singleton compartida entre todos los contenedores en hiearchy.HierarchicalLifetimeManager
- deriva el comportamiento deContainerControlledLifetimeManager
. Proporciona una instancia "singleton" por contenedor en hiearchy (subcontenedores).ExternallyControlledLifetimeManager
- sin manipulación de eliminación. Corrija el comportamiento porque el contenedor no es el propietario de la instancia.PerResolveLifetimeManager
- sin manejo de eliminación. En general es el mismo queTransientLifetimeManager
, pero permite reutilizar la instancia para la inyección de dependencia al resolver el gráfico de objetos completos.PerThreadLifetimeManager
- no se maneja la eliminación como también se describe en MSDN. ¿Quién es responsable de eliminar?
Implementación de acumulación en PerThreadLifetimeManager
es:
public class PerThreadLifetimeManager : LifetimeManager
{
private readonly Guid key = Guid.NewGuid();
[ThreadStatic]
private static Dictionary<Guid, object> values;
private static void EnsureValues()
{
if (values == null)
{
values = new Dictionary<Guid, object>();
}
}
public override object GetValue()
{
object result;
EnsureValues();
values.TryGetValue(this.key, out result);
return result;
}
public override void RemoveValue()
{ }
public override void SetValue(object newValue)
{
EnsureValues();
values[this.key] = newValue;
}
}
contenedor para desechar casos no dispone desechables creados con este gestor de toda la vida. La finalización del hilo tampoco eliminará esas instancias. Entonces, ¿quién es responsable de liberar instancias?
Intenté eliminar manualmente la instancia resuelta en el código y encontré otro problema. No puedo desmontar el instinto. RemoveValue of lifetime manager está vacío: una vez que se crea la instancia, no es posible eliminarla del thread static dictionary (también sospecho que el método TearDown
no hace nada). Por lo tanto, si llama al Resolve
después de eliminar la instancia, se eliminará la instancia. Creo que esto puede ser un gran problema cuando se utiliza este administrador de por vida con subprocesos del grupo de subprocesos.
¿Cómo utilizar correctamente este administrador de por vida?
Además, esta implementación a menudo se reutiliza en administradores personalizados de por vida como PerCallContext, PerHttpRequest, PerAspNetSession, PerWcfCall, etc. Sólo el diccionario estático de hilos se reemplaza con algún otro constructo.
También entiendo correctamente que el manejo de objetos desechables depende del administrador de por vida? Entonces, el código de la aplicación depende del administrador de por vida utilizado.
He leído que en otros contenedores IoC que se ocupan de objetos desechables temporales es manejado por subcontenedores, pero no encontré un ejemplo para Unity, probablemente podría manejarse con subcontainer con alcance local y HiearchicalLifetimeManager
pero no estoy seguro de cómo hacerlo eso.
Posiblemente se trata de hacer que Unity implemente de forma determinista el comportamiento de eliminación implementando vidas útiles personalizadas, pero es demasiado complicado de explicar aquí. En mi libro uso más de seis páginas solo para explicar cómo hacer esto: http://affiliate.manning.com/idevaffiliate.php?id=1150_236 –
Solo use un contenedor mejor. –
@Mark: Desafortunadamente su libro será publicado en agosto y no me gusta el MEAP. –