Inyeccion de dependencias de .NET Core – #3 TransientAndDispose

Bien, esta será la última entrada por ahora de esta pequeña serie acerca de elementos con los que tenemos que tener cuidado cuando trabajemos con inyección de dependencias en .NET Core. En esta ocasión hablaremos sobre como funciona el ciclo de vida de nuestras dependencias y cuando se liberan los recursos de las mismas. Paria ello, vamos a empezar con la misma clase que hemos utilizado en esta serie, aunque ahora implementando IDisposable.

Bien, el sistema de DI de .NET Core nos asegura que la llamada a nuestro método Dispose se realizará  una vez que el proveedor finalize su ámbito. Por el código que estoy viendo últimamente, mucha gente tiende a registrar ciertos componentes usando directamente el IServiceProvider que tenemos en nuestro método de configuración, que generalmente vivirá todo el tiempo que viva nuestra aplicación web. Por lo tanto, todas estas dependencias transient seguirán vivas en nuestras aplicaciones, haciendo que la memoria crezca ad infinitum. Vamos a ilustrar este caso con un sencillo ejemplo.

Si cuando acaba la ejecución de este bucle revisáramos los miembros de nuestro provider veriamos un campo llamado _transientDisposables que mantienen una referencia a las 1000 dependencias que hemos resuelto del contenedor.

Por supuesto, esto no sucede en un ciclo normal de una aplicación ASP.NET Core puesto que las mismas se hacen en un scope que después es limpiado. Vendría ser algo como lo siguiente:

El corolario de esta entrada es entonces.. ten cuidado de que proveedor haces la resolución de tus dependencias, ten cuidado que el mismo se libere y todos tus objetos disposables puedan a su vez liberar recursos. Revisa _transientDisposables para obtener posible información de fugas de memoria.

 

Saludos

Unai

Inyeccion de dependencias de .NET Core – #2 Scoped2Singleton

Continuando con la serie empezada con los deadlock en la inyeccion de dependencias de .NET Core en esta ocasión vamos a hablar de otra práctica erronea como asignar una dependencia de tipo Scope a un componente registrado como Singleton. Empezaremos como siempre ilustrándolo con un pequeño ejemplo, dónde usaremos las mismas clases que en la entrada anterior:

Estas clases las registraremos como sigue:

Como observas, tenemos un componente SomeClass registrado como Singleton pero que depende de DependencyClass que está a su vez registrada como Scoped. El problema de este tipo de registros es que si no pensamos en realidad lo que estamos diciendo podemos pasar por alto que esta dependencia Scoped en realidad se convertirá en Singleton y, por lo tanto, podremos tener muchos problemas si no lo tenemos en consideración. Vamos a comprobarlo agregando el siguiente código después del registro de nuestras dependencias:

En el código anterior estamos simulando la creación de diferentes scopes, recuerde que en una aplicación ASP.NET Core cada request sería un nuevo Scope. Si observamos el HashCode de cada elemento Dependency nos será fácil ver que siempre tenemos el mismo valor.

Como hemos dicho al principio, esto no es un bug sino una consideración que tenemos que tener y ser consicente de ella, toda dependencia scope de un singleton se convierte en singleton.

En .NET Core 1.1 tenemos un pequeño flag para indicarle a nuestro sistema de DI que nos avise sobre estos posibles errores. Con el uso de este flag en la situación anterior se lanzaría una excepcion al intentar resolver SomeClass. En el siguiente fragmento podemos ver el codigo completo con el uso de este flag.

 

Saludos

Unai Zorrilla

Inyeccion de dependencias de .NET Core – #1 DeadLocks

A lo largo de esta serie de post que hoy empieza no quiero repetir muchos de los elementos que ya tenemos en la propia documentación oficial de .NET Core. El nuevo portal de documentación Microsoft Docs ya tiene mucha información sobre Quick Starts y los elementos más comunes, por lo que escribir sobre eso creo que no aporta demasiado. Incluso en el libro de introducción a .NET Core puedes ver muchos conceptos y prácticas más allá de estos “comienzos”.  En esta serie de entradas me gustaría hablar de ciertos aspectos problemáticos o con los que podemos tener problemas si no los tenemos en consideración. Continúa leyendo Inyeccion de dependencias de .NET Core – #1 DeadLocks