Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

341
Vistas
¿Cómo permitir servicios opcionales con Microsoft.Extension.DependencyInjection?

Estoy jugando con ASP.NET Core en mi propio proyecto de pasatiempo, quiero crear un marco que será consumido por un desarrollador y quiero permitir el servicio opcional y usar valores predeterminados si no están registrados.

Recibo el error Unable to resolve service for type 'XXX' , pero preferiría que el DI devuelva un null en lugar de lanzar una excepción. Quiero permitir servicios opcionales, por lo que si se encuentra un servicio, utilícelo en el constructor, si no lo encuentra, pase nulo al constructor.

En mi implementación tengo:

 public IServiceManager(IService service, ...) { _service = service ?? new DefaultService(); ... }

Entonces, como puede ver, si no se puede encontrar el servicio (nulo), use el valor predeterminado. Tal vez estoy malinterpretando cómo funciona DI. ¿Quizás podría usar una fábrica para hacer esto en su lugar? Sin embargo, en mi sistema, el uso de servicios predeterminados cuando no se proporcionan será una ocurrencia común, por lo que necesito una solución que no requiera que el consumidor de la API registre un servicio.

¿Hay alguna manera de configurar ASP.NET Core DI para devolver un valor nulo en lugar de lanzar una excepción?

about 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Agregue valor predeterminado a ese parámetro en el constructor.

 public IServiceManager(IService service = null, ...) { _service = service ?? new DefaultService(); ... }
about 4 years ago · Santiago Trujillo Denunciar

0

Por su propia naturaleza, la inyección de constructor siempre se considera obligatoria.

Las primeras versiones de Microsoft DI (no me gusta usar el término ASP.NET Core DI, porque no depende de ASP.NET Core y se puede usar fuera de él) solo admitían el constructor con la mayoría de los parámetros.

Creo que esto se ha cambiado desde entonces para permitir múltiples constructores y el contenedor IoC elegirá uno adecuado. Dicho esto, es probable que necesite definir varios constructores.

 public IServiceManager(IService service, IOtherService otherService) { } public IServiceManager(IOtherService otherService) { }

Luego, se debe llamar al segundo constructor, si IService no está registrado con el contenedor IoC.

Pero sigue siendo una práctica bastante cuestionable en el mejor de los casos y hace que su código sea más difícil de mantener y mantener su acoplamiento invariable/flojo.

Nunca debería tener que crear instancias de sus tipos dentro de sus servicios, ni siquiera para servicios opcionales.

En su lugar, debe proporcionar registros que permitan a un usuario anularlos con sus propias implementaciones.

 public static IServiceCollection AddMyLibrary(this IServiceCollection services) { services.TryAddTransient<IService, Service>(); services.TryAddTransient<IOtherService, OtherService>(); }

Entonces el usuario lo anula.

 services.AddTransient<IService, CustomService>(); services.AddMyLibrary();

Ahora CustomService se inyectará donde se solicite IService .

about 4 years ago · Santiago Trujillo Denunciar

0

Lo más fácil sería registrar el componente DefaultService en sí mismo para el servicio IService dentro de su contenedor IoC; estoy usando la terminología de Castle Windsor. La mayoría de los contenedores permiten registrar múltiples componentes para un servicio. En caso de que no registre un componente personalizado para el servicio (otra implementación de IService), se resolverá e inyectará DefaultService; de lo contrario, su componente personalizado se resolverá para el servicio, simplemente registre los componentes en el orden correcto (en Castle Windsor, el componente registrado primero se considerará: componentes múltiples para un servicio )

 WindsorContainer container = new WindsorContainer(); container.Register(Component.For<IServiceManager>().ImplementedBy<ServiceManager>()); container.Register(Component.For<IService>().ImplementedBy<CustomService>()); container.Register(Component.For<IService>().ImplementedBy<DefaultService>()); IServiceManager serviceManager = container.Resolve<IServiceManager>(); IService service = ((ServiceManager)serviceManager).Service; // service is of type CustomService

Con respecto al siguiente comentario de @Tseng:

Esto supera la idea de tener un contenedor de inyección de dependencia/IoC en primer lugar, cuando lo instancias dentro del constructor.

No siempre es el caso... Si tiene una dependencia opcional , primero, defínala como una propiedad con un setter público , para que el componente se pueda inyectar si está registrado. En caso de que no haya ningún componente registrado (por lo tanto, el contenedor no establece la propiedad), creo que puede ser aceptable instanciar el componente predeterminado a través de la nueva palabra clave "peligrosa". Todo depende del contexto: para ser claros, no crearía una instancia de un servicio manualmente, pero siempre hay excepciones.

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda