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 interfazIQueryable<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 interfazIEnumerable<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 ORMNotSupportedException
? . , , , LSP. , ,IQueryable<T>
, , .
, , , . , Entity Framework, Microsoft OData. , IQueryable<T>
, — ( ). Null Object, IQueryable<T>
, , .
:
public interface IRepository
{
IQueryable<T> Query<T>();
}
LSP , , , , ( ) , . . , , ORM, , , , ORM. .
ORM, . . , . . , SQL Event Store.
— .
- Más sobre el dispositivo
IQueryable
yIQueryProvider
en el artículo " Cómo funcionan los proveedores de datos IQueryable y LINQ ".- Sobre la creación de sus propios proveedores de consultas en la charla homónima de Anton Tretyakov de DotNext Moscow 2019 .