2017-10-13 2 views
2

J'ai une interface que je souhaite utiliser pour effectuer une vérification de validité, aussi simple que de passer un identifiant dans une méthode et il devrait retourner vrai ou faux si cette entité existe. Je ne veux pas avoir cette implémentation pour chacun de mes dépôts, j'ai donc créé une interface distincte IValidityCheck<T> where T: DbSet<T> comme indiqué ci-dessous.Comment utiliser injection de dépendance avec dbset générique <T>

public interface IValidityCheck<T> where T: DbSet<T> 
{ 
    bool IsValid(Guid id, T entitySet); 
} 

Maintenant dans mon application de base de .net, j'essaye d'ajouter la dépendance pour ceci. J'ai quelque chose comme.

services.AddTransient<IValidityCheck<DbSet<School>>, ValidityCheck<DbSet<School>>>(); 

mais je reçois une erreur comme

Le type 'Microsoft.EntityFrameworkCore.DbSet' ne peut pas être utilisé comme paramètre de type 'T' dans le type générique ou méthode 'IValidityCheck'. Il n'y a pas de conversion de référence implicite de « Microsoft.EntityFrameworkCore.DbSet » à « Microsoft.EntityFrameworkCore.DbSet> »

Je sais changer à la contrainte de where T: class sera plus facile, mais je veux la contrainte être spécifique à DbSet

+0

Comment T peut être un DbSet ? Je pense que vous avez besoin d'une autre variable générique –

+0

Votre définition est comme une boucle récursive infinie. Que diriez-vous 'l'interface publique IValidityCheck où T: DbSet ' et 'services.AddTransient , école>, ValidityCheck , école >>();' –

Répondre

2

Vous avez 2 options:

1) Vous devrez peut-être un autre paramètre. Comme ceci:

public interface IValidityCheck<T, I> where T: DbSet<I> 

et l'utiliser comme ceci:

services.AddTransient<IValidityCheck<DbSet<School>, School>, ValidityCheck<DbSet<School>,School>>(); 

2) Une autre possibilité est que vous pourriez abstraite DbSet loin en introduisant une interface plus:

public interface IValidityCheckBase<T> where T: class 
{ 
    bool IsValid(Guid id, T entitySet); 
} 

public interface IValidityCheck<T> : IValidityCheckBase<DbSet<T>> 
{ 

} 

Votre exemple générique mise en oeuvre:

public class ValidityCheck<T> : IValidityCheck<T> 
    { 
     public bool IsValid(Guid id, DbSet<T> entitySet) 
     { 
      return false; 
     } 
    } 

Ensuite, il devrait fonctionner même sans déclarer DbSet dans votre utilisation de type générique parce que vous voulez forcer à DbSet de toute façon, cela devrait être plus concise:

services.AddTransient<IValidityCheck<School>, ValidityCheck<School>>(); 

Dans ce DEMO, j'utilise List<T> à la place, mais ça devrait être similaire. Personnellement, j'aime l'option 2). Vous voyez que le code se compile très bien dans la démo.