J'essaie de créer une maquette pour mon interface IRepository
:
public interface IRepository<T> : ICollection<T>, IQueryable<T>
{
}
Avec cette implémentation:
public class RepositoryFake<T> : List<T>, IRepository<T>
{
public Expression Expression
{
get
{
return this.AsQueryable().Expression;
}
}
public Type ElementType
{
get
{
return this.AsQueryable().ElementType;
}
}
public IQueryProvider Provider
{
get
{
return this.AsQueryable().Provider;
}
}
}
Mais lorsque je l'utilise, j'obtiens une exception StackOverflow
. Comment implémenter correctement cette interface pour pouvoir utiliser uniquement une List
en tant que référentiel?
L'utilisation est très simple
[Test]
public void Test()
{
RepositoryFake<User> users = new RepositoryFake<User>();
users.Add(new User());
List<User> list = (from user in users
where user.Id == "5"
select user).ToList();
Assert.That(list, Is.Empty);
}
Voici une capture d'écran de l'exception:
La raison de votre problème est que si vous exécutez AsQueryable
, il vérifie si l’objet implémente déjà IQueryable
et si yes le renvoie.
Utilisez new EnumerableQuery<T>(this)
au lieu de AsQueryable
qui n’effectue pas cette vérification.
Solution de contournement pour .net 3.5:
return ((IEnumerable<T>)this).Select(x=>x).AsQueryable()
Les premiers lancements sur IEnumerable<T>
de sorte que la méthode Select
choisie sera Enumerable.Select
et non Queryable.Select
. La sélection d'identité renverra alors un nouvel objet qui n'implémentera pas IQueryable<T>
. Par conséquent, la vérification de son implémentation dans AsQueryable
échoue.
Essayez d’utiliser base.AsQueryable()
au lieu de this.AsQueryable()
.