Mecanismo para la inyección de dependencias para proporcionar la implementación más específica de una interfaz de servicio genérica

Siento que jugué bingo de palabra de moda con el título. Aquí hay un ejemplo conciso de lo que estoy preguntando. Digamos que tengo alguna jerarquía de herencia para algunas entidades.

class BaseEntity { ... }
class ChildAEntity : BaseEntity { ... }
class GrandChildAEntity : ChildAEntity { ... }
class ChildBEntity : BaseEntity { ... }

Ahora digamos que tengo una interfaz genérica para un servicio con un método que utiliza la clase base:

interface IEntityService<T> where T : BaseEntity { void DoSomething(BaseEntity entity)... }

Tengo algunas implementaciones concretas:

class BaseEntityService : IEntityService<BaseEntity> { ... }
class GrandChildAEntityService : IEntityService<GrandChildAEntity> { ... }
class ChildBEntityService : IEntityService<ChildBEntity> { ... }

Supongo que he registrado todo esto con el contenedor. Así que ahora mi pregunta es si estoy iterando a través de unaList deBaseEntity ¿Cómo obtengo el servicio registrado con la coincidencia más cercana?

var entities = List<BaseEntity>();
// ...
foreach(var entity in entities)
{
    // Get the most specific service?
    var service = GetService(entity.GetType()); // Maybe?
    service.DoSomething(entity);
}

o que me gustaría hacer es tener un mecanismo configurado de modo que si una entidad tiene un tipo deClassA el método no encontraría ningún servicio para la clase específica y, por lo tanto, devolveríaBaseEntityService. Más tarde, si alguien vino y agregó un registro para este servicio:

class ClassAEntityService : IEntityService<ChildAEntity> { ... }

El hipotéticoGetServicel método @ comenzaría a proporcionar elClassAEntityService Para elClassA tipos sin requerir más cambios de código. Por el contrario, si alguien vino y simplemente eliminó todos los servicios, exceptoBaseEntityService entonces laGetServicel método @ devolvería eso para todas las clases que hereden deBaseEntity.

Estoy bastante seguro de que podría rodar algo incluso si el contenedor DI que estoy usando no lo admite directamente. ¿Estoy cayendo en una trampa aquí? ¿Es este un anti patrón?

EDITAR

Algunas discusiones con @Funk (ver más abajo) y algunas búsquedas adicionales en Google, esas discusiones me hicieron pensar que buscar me ha hecho agregar más palabras de moda a esto. Parece que estoy tratando de recopilar todas las ventajas de DI Containers, el Patrón de estrategia y el Patrón de decorador de una manera segura y sin usar un Patrón de localización de servicios. Estoy empezando a preguntarme si la respuesta es "Usar un lenguaje funcional".

Respuestas a la pregunta(3)

Su respuesta a la pregunta