IQueryable crea una fuerte cohesión

De vez en cuando me encuentro con personas que intentan expresar una API en términos de IQueryable<T>



. Casi siempre es una mala idea. En este artículo explicaré por qué. En resumen, IQueryable<T>



este es uno de los mejores ejemplos de la interfaz de encabezado que ofrece el marco .NET. Es casi imposible implementarlo por completo.







Este artículo trata sobre los desafíos de implementar una API basada en una interfaz IQueryable<T>



. Esta no es una queja sobre la interfaz como tal. Aparte de eso, esto no es un reclamo de los maravillosos métodos LINQ disponibles para la interfaz IEnumerable<T>



.

Podemos decir que IQueryable<T>



esta es una violación continua del principio de sustitución de Liskov . Voy a utilizar la ley de Postel para explicar por qué esto es así.







El Principio de Sostenibilidad, también conocido como Ley de Postel en honor a John Postel : "Sea liberal en lo que acepta y conservador en lo que envía".


Usando IQueryable<T>





La primera parte de la ley de Postel, cuando se aplica al diseño de API, es que la API debe ser liberal con respecto a lo que acepta . En otras palabras, estamos hablando de parámetros de entrada. Por lo tanto, la API receptora IQueryable<T>



podría verse así:







IFoo SomeMethod(IQueryable<Bar> q);
      
      





¿Es esta API lo suficientemente liberal ? Definitivamente no. Tal interfaz requiere que el código de llamada pase una implementación IQueryable<Bar>



. De acuerdo con el principio de sustitución de Liskov, el programa debe permanecer correcto para todas las implementaciones de interfaz. Esto se aplica tanto a la implementación IQueryable<Bar>



como a la implementación SomeMethod



.







IQueryable<T>



: (Query Provider). , Bar



, . , , - , , — SQL. .







, ( ), ? SomeMethod



? , , , . , .







, , . , Query Objects , , .









IFoo FindById(int fooId);
      
      





IFoo FindByCorrelationId(int correlationId);
      
      







IEnumerable<IFoo> GetFoos(int page);
      
      





, . API, (Role Interfaces) , .







IQueryable<T>





, API , . , , . , IQueryable<T>



:







IQueryable<Bar> GetBars();
      
      





API ( ). , . , IQueryable <Bar>



, IQueryable <Bar>



.







? LSP, , IQueryable<Bar>



, . . ?









IQueryable<T>



— . , IQueryable Microsoft. , , , , .









- Entity Framework ORM NotSupportedException



? . , , , LSP. , , IQueryable<T>



, , .

, , , . , Entity Framework, Microsoft OData. , IQueryable<T>



, — ( ). Null Object, IQueryable<T>



, , .









, , . API , , .







:







public interface IRepository
{
    IQueryable<T> Query<T>();
}
      
      





LSP , , , , ( ) , . . , , ORM, , , , ORM. .

ORM, . . , . . , SQL Event Store.







.












All Articles