Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

340
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!