https://autofac.readthedocs.io/en/latest/lifetime/disposal.html
Los recursos obtenidos dentro de una unidad de trabajo - Conexiones de base de datos, transacciones, las sesiones autenticadas, manipuladores de archivos, etc. - deben desecharse cuando ese trabajo se haya completado. .NET proporciona la IDisposable
interfaz para ayudar en esta noción más determinista de la eliminación.
Algunos contenedores IoC necesitan que se les diga explícitamente a disponer de un caso particular, a través de un método como ReleaseInstance()
. Esto hace que sea muy difícil garantizar que se usan la semántica correcta colocación.
- Cambio de implementaciones de un no desechable a un componente desechable puede significar la modificación de código de cliente.
- El código de cliente que pueden haber ignorado disposición cuando el uso de instancias compartidas es casi seguro que dejar de limpiar cuando se cambia a casos no compartidas.
Autofac resuelve estos problemas utilizando endoscopios de toda la vida como una forma de deshacerse de todos los componentes creados durante una unidad de trabajo.
using (var scope = container.BeginLifetimeScope()) { scope.Resolve<DisposableComponent>().DoSomething(); // Components for scope disposed here, at the // end of the 'using' statement when the scope // itself is disposed. }
Se crea un alcance vida cuando una unidad de trabajo comienza, y cuando esa unidad de trabajo se haya completado el contenedor anidado puede disponer todas las instancias dentro de ella que están fuera de alcance.
componentes registro
Autofac puede disponer automáticamente de algunos componentes, pero usted tiene la posibilidad de especificar manualmente un mecanismo de eliminación, también.
Los componentes deben ser registrados como InstancePerDependency()
(el valor predeterminado) o alguna variación de InstancePerLifetimeScope()
(por ejemplo, InstancePerMatchingLifetimeScope()
o InstancePerRequest()
).
Si tiene componentes Singleton (registradas como SingleInstance()
) que van a vivir para la vida del contenedor . Desde tiempos de vida de contenedores son por lo general el tiempo de vida de aplicaciones, significa que el componente no estará dispuesto hasta el final de la aplicación.
eliminación automática
Para aprovechar las ventajas de la eliminación automática determinista, su componente debe implementar IDisposable
. A continuación, puede registrar su componente según sea necesario y al final de cada ámbito curso de la vida en el que se resuelve el componente, el Dispose()
será llamado método en el componente.
var constructor = nuevo ContainerBuilder (); builder.RegisterType <SomeDisposableComponent> (); var contenedor = builder.Build (); // crear ámbitos de por vida anidados, determinación // el componente, y disponer de los alcances. // Su componente se dispone con el alcance.
Soporte eliminación asíncrona
Si el comportamiento de eliminación de sus componentes requiere algún tipo de actividad de E / S, tales como el lavado de un buffer en un archivo, o enviar un paquete por la red para cerrar una conexión, entonces es posible que desee considerar la implementación de la nueva .NET IAsyncDisposable interfaz.
En Autofac 5,0, se añadió el apoyo a la IAsyncDisposable
interfaz, por lo alcances de toda la vida ahora se pueden disponer de forma asíncrona:
clase MyComponent: IDisposable, IAsyncDisposable { INetworkResource myresource; pública vacío Dispose () { myResource.Close (); } Pública asíncrono ValueTask DisposeAsync () { esperan ser myResource.CloseAsync (); } } // ... Aguarde usando ( var alcance = container.BeginLifetimeScope) () { var servicio scope.Resolve = <MyComponent> (): // DisposeAsync se llamará en MyComponent // cuando las salidas utilizando bloques. }
Cuando un alcance toda la vida está dispuesto de forma asíncrona, cualquiera de los componentes registrados que implementan IAsyncDisposable
además de IDisposable
tendrán su DisposeAsync()
método invocado, en lugar del Dispose()
método
Si un componente sólo implementa el síncrona Dispose()
método, entonces todavía se invoca cuando el alcance toda la vida está dispuesto de forma asincrónica.
Cuando se utiliza Autofac con el Core Integración ASP.NET, todos los ámbitos por-petición de toda la vida están dispuestas de forma asincrónica.
Importante
Mientras que usted no tiene que poner en práctica
IDisposable
si se implementaIAsyncDisposable
, le recomendamos que lo haga.Si su único implementos de componentes
IAsyncDisposable
, pero dispone de alguien del ámbito de forma sincrónica, entonces Autofac arrojará una excepción, ya que no sabe cómo deshacerse de su componente.
eliminación especificado
Si el componente no implementa IDisposable
pero todavía requiere un poco de limpieza al final de un ámbito de la vida, puede utilizar la vida evento OnRelease .
var constructor = nuevo ContainerBuilder (); builder.RegisterType <SomeComponent> () .OnRelease (ejemplo => instance.CleanUp ()); var contenedor = builder.Build (); // crear ámbitos de por vida anidados, determinación // el componente, y disponer de los alcances. // de su componente "CleanUp ()" método será // llama cuando el alcance está dispuesto.
Tenga en cuenta que OnRelease()
anula el modo predeterminado de IDisposable.Dispose()
. Si el componente de ambos instrumentos IDisposable
y requiere algún otro método de limpieza, usted necesitará a la llamada manualmente Dispose()
en OnRelease()
o tendrá que actualizar su clase por lo que el método de limpieza es llamado desde el interior Dispose()
.