2017-01-18 1 views
0

J'ai un service générique qui effectue les mêmes actions contre toute combinaison requête/réponse donnée. La seule fois où quelque chose de spécifique arrive est quand il s'agit de la persistance. J'essaie d'injecter une implémentation spécifique d'un référentiel basé sur l'un des types (TRequest) utilisés. Jusqu'à présent, j'ai ci-dessous, mais Ninject et les tests d'intégration échouant à trouver un référentiel qui correspond à ce qu'il recherche, un référentiel de type EntityBase. Je pensais que ce serait bien que mes entités spécifiques héritent de EntityBase ...C# Argument de méthode de Type IRepository <BaseType> n'accepte pas l'implémentation héritant de BaseType

Erreur CS1503 Argument 1: ne peut pas convertir 'Repositories.IRepository < Models.PersonModel>' à « Repositories.IRepository < Models.EntityBase> '

EDIT: Je sais pourquoi im obtenir l'erreur actuelle, son assez explicite. Des idées comment je peux y parvenir?

PersonModel.cs

public class PersonModel : EntityBase 
{ 
    blah blah 
} 

IRepository.cs

public interface IRepository<T> 
{ 
    T Get(int id); 
    void Add(T entity); 
    void Delete(int id); 
} 

PersonRepository.cs

public class PersonRepository : IRepository<PersonModel> 
{ 
    blah blah 
} 

Service.cs

public class Service<TRequest, TResponse> : IService<TRequest, TResponse> 
{ 
    private readonly IRepository<EntityBase> _repository; 

    public Service(IRepository<EntityBase> repository) 
    { 
     _respository = repository 
    } 

    public TResponse Call(TRequest request) 
    { 
     var requestEntity = MapperFactory.GetMapperFor(typeof(TRequest)).Map(request); 

     _repository.Add(requestEntity) 

     blah blah blah return    
    } 
} 

IoCModule.cs

Bind<IRepository<PersonModel>>().To<PersonRepository>(); 
+0

Je ne suis pas sûr de bien comprendre le code (Ninject), mais peut-être que votre module IoC devrait 'Bind >(). ();'. Je ne sais pas comment la partie 'To ()' détermine comment créer l'instance de classe. J'essaie juste d'aider. Ou cela va simplement déplacer le problème à un autre endroit – bixarrio

+1

Si 'TRequest' hérite de' EntityBase' vous pouvez changer 'IRepository ' –

+0

Je suis d'accord avec @ArturoMenchaca. Sur la base de 'Call (demande TRequest)' dans le service, le référentiel doit être 'IRepository '. – bixarrio

Répondre

1

En effet, même si PersonModel hérite de EntityBase, cela ne signifie pas que IRepository<PersonModel> hérite de IRepository<EntityBase>.

Une façon possible de traiter ce problème est d'avoir un troisième type générique:

public class Service<TRequest, TResponse, T> : IService<TRequest, TResponse, T> 
{ 
    private readonly IRepository<T> _repository; 
} 

Ou une autre façon est de préciser le type de service:

public class PersonService<TRequest, TResponse> : IService<TRequest, TResponse> 
{ 
    private readonly IRepository<PersonModel> _repository; 
} 
+0

Je vais reformuler ma question, je demande comment réaliser ce que je suis en train de décrire. Mais merci. –

+0

Bonne idée, je vais essayer le service spécifique. –

+0

Cest fait le tour merci –

0

Parce que Repositories.IRepository<Models.PersonModel> et Repositories.IRepository<Models.EntityBase> sont types effectivement différents.

+0

Yee je reçois cela, devinez im demander des idées sur la façon dont je peux y parvenir. –

1

Parce que votre IRepository < T> T utilise comme paramètre (entrée), vous ne pouvez pas faire IRepository < T> covariant qui permettrait ainsi à l'attribution IRepository < PersonModel> à IRepository < EntityBase>. Donc IoC ne peut pas travailler ici.

Vous devrez écrire des tests unitaires spécifiques à chaque implémentation pour IRepository < T>, au lieu de vous appuyer sur un test générique pour IRepository < EntityBase>.

+0

merci pour une explication utile –