2008-12-08 5 views
4

J'utilise une interface de référentiel générique qui me permet d'ajouter, de rechercher, de mettre à jour et de supprimer des objets de différents types. J'ai ensuite implémenté deux référentiels concrets et je peux les changer sans changer l'application. Tout est merveilleusement déconnecté. Mais j'ai frappé un hic. Le code à l'intérieur de mes méthodes de dépôt se sent mal et je n'arrive pas à comprendre comment le faire mieux. Voici un extrait de mon code:.net architecture: Création d'un référentiel <T> générique

public class OracleRepository<T> : IRepository<T> where T : new() 
{ 
    public IQueryable<T> GetAll() 
    { 
     if (typeof(T) == typeof(Object1)) 
     { 
      return (IQueryable<T>)DataAccess.GetAllObject1().AsQueryable(); 

     } 

     if (typeof(T) == typeof(Object2)) 
     { 
      return (IQueryable<T>)DataAccess.GetAllObject2().AsQueryable(); 
     } 

     throw new NotImplementedException(); 
    } 
} 

Le problème est que mon DataAccess (crée des objets à partir d'un datareader) n'est pas générique et a des méthodes spécifiques pour chaque type d'objet qu'il prend en charge. Puis-je réécrire ce qui précède afin d'éviter la liste de if-then-else si j'utilise des génériques ou autres?

+0

La réponse la plus simple ne serait-elle pas de renvoyer un objet de DataAccess (en passant le type ou quelque chose) ou d'utiliser NHibernate ou Linq To SQL? – gcores

Répondre

11

Un modèle courant consiste à utiliser un dictionnaire de type à une fonction du type approprié. Par exemple:

private static readonly IDictionary<Type, Func<object>> Fetchers = 
    new Dictionary<Type, Func<object>>(); 
    { 
     (typeof(Object1),() => DataAccess.GetAllObject1().AsQueryable()), 
     (typeof(Object2),() => DataAccess.GetAllObject2().AsQueryable()), 
     // etc 
    }; 

public IQueryable<T> GetAll() 
{ 
    Func<object> func = Fetchers[typeof(T)]; 
    if (func == null) 
    { 
     throw new NotImplementedException(); 
    } 
    return (IQueryable<T>) func(); 
} 

Le casting est là parce que vous ne pouvez pas vraiment exprimer la relation de type dans le dictionnaire, mais au moins il est légèrement plus facile d'ajouter de nouveaux types etc.

Vous pourriez être en mesure de se déplacer l'appel à AsQueryable() à GetAll() en fonction de ce que GetAllObject1() etc retour.

Questions connexes