Publicaciones
Cuándo usar el atributo FromService
20 de noviembre de 2019 • 3 min de lectura
Recientemente descubrí el atributo [FromServices], que ha sido parte de .Net Core desde la primera versión.
El atributo [FromServices] permite inyección de dependencias a nivel de método en controladores de Asp.Net Core.
Aquí hay un ejemplo:
public class UserController : Controller
{
private readonly IApplicationSettings _applicationSettings;
public UserController(IApplicationSettings applicationSettings)
{
_applicationSettings = applicationSettings;
}
public IActionResult Get([FromService]IUserRepository userRepository, int userId)
{
//Do magic
}
}
¿Por qué usar inyección de método en lugar de inyección de constructor? La explicación común es cuando un método necesita dependencias y no se usa en ningún otro lugar, entonces es candidato para usar el atributo [FromService].
Steven de StackOverflow publicó una respuesta en contra del uso del atributo [FromService]:
Para mí, el uso de este tipo de inyección de método en acciones de controlador es una mala idea, porque:
– El atributo
[FromServices]puede olvidarse fácilmente, y solo lo descubrirás cuando se invoque la acción (en lugar de descubrirlo al iniciar la aplicación, donde puedes verificar la configuración de la aplicación)– La necesidad de alejarse de la inyección de constructor por razones de rendimiento es una indicación clara de que los componentes inyectados son demasiado pesados para crear, mientras que los constructores de inyección deben ser simples, y la creación de componentes debe, por lo tanto, ser muy ligera.
– La necesidad de alejarse de la inyección de constructor para evitar que los constructores se vuelvan demasiado grandes es una indicación de que tus clases tienen demasiadas dependencias y se están volviendo demasiado complejas. En otras palabras, tener muchas dependencias es una indicación de que la clase viola el Principio de Responsabilidad Única. El hecho de que tus acciones de controlador puedan dividirse fácilmente en diferentes clases es una prueba de que tal controlador no es muy cohesivo y, por lo tanto, una indicación de una violación de SRP.
Entonces, en lugar de ocultar el problema raíz con el uso de inyección de método, te aconsejo que uses la inyección de constructor como único patrón de inyección aquí y hagas tus controladores más pequeños. Esto podría significar, sin embargo, que tu esquema de enrutamiento sea diferente de tu estructura de clases, pero esto está perfectamente bien y completamente soportado por ASP.NET Core.
Desde una perspectiva de capacidad de prueba, por cierto, realmente no debería importar si a veces hay una dependencia que no es necesaria. Hay patrones de prueba efectivos que solucionan este problema.
Estoy de acuerdo con Steven; si necesitas mover tus dependencias de tu controlador al método porque la clase está construyendo demasiadas dependencias, entonces es hora de dividir el controlador. Casi con certeza estás violando el SRP.
El único caso de uso que veo con inyección de método es el enlace tardío cuando una dependencia no está lista en la construcción del controlador. De lo contrario, es mejor usar inyección de constructor.
Digo esto porque con inyección de constructor la clase sabe en la construcción si las dependencias están disponibles. Con inyección de método, este no es el caso, no se sabe si las dependencias están disponibles hasta que se llama al método.
Autor: Chuck Conway es un Ingeniero de IA con casi 30 años de experiencia en ingeniería de software. Construye sistemas de IA prácticos—canalizaciones de contenido, agentes de infraestructura y herramientas que resuelven problemas reales—y comparte lo que está aprendiendo en el camino. Conéctate con él en redes sociales: X (@chuckconway) o visítalo en YouTube y en SubStack.