2010-07-16 10 views
1

J'ai un service Web qui fournit une interface pour interroger des données. J'écris une application WPF en utilisant MVVM. Je travaille sur la création d'un référentiel que mes View Models peuvent utiliser pour récupérer des modèles. Le référentiel appellera le service Web pour récupérer les données, si nécessaire.WPF MVVM - Requête de modèle de référentiel

Je voudrais divers trouver méthodes dans mon référentiel qui trouve les données basées sur divers critères et pas seulement un critère comme «Id».

Dans mon dépôt, j'ai créé une méthode Find qui prend une Spécification comme entrée

void IList<MyData> Find (ISpecification spec) 

où une interface ISpecification de base est

public interface ISpecification<T> 
{ 
    bool IsSatisfiedBy(T candidate); 
} 

Un implemenation haut niveau de la méthode Find serait comme suit

  • première searche s le cache pour les candidats qui satisfont les spécifications
  • Si touvée la liste des candidats
  • utiliser Sinon les spécifications/critères pour appeler le service Web pour aller chercher les candidats et retourner la liste

Je suis confus au sujet de la Autre scénario ci-dessus - Quelle est la bonne façon de concevoir la spécification de sorte que si je n'ai pas de données dans le cache du référentiel qui satisfasse la spécification, je devrais être capable de récupérer les critères de spécification et appeler le service web passant la méthode web?

Quelques choses sur mon esprit-

  • Si je me spécialise trouver des méthodes pour prendre spécifications spécialisées qui ont des propriétés/critères puis référentiel - Spécification a couplage étroit
  • Si j'aurais à se connecter directement à DB (ce que je ne suis pas) alors j'aurais pu supporter une méthode qui renvoie un SQL par exemple. LINQ aurait pu être une option, etc.

Répondre

2

Pourquoi n'utilisez-vous pas une expression linq comme entrée de paramètre?

par exemple.

public class MyModel 
{ 
    public int Prop1 {get;set;} 
    public string Prop2 {get;set;} 
} 

public interface IRepository 
{ 
    T Find<T>(Expression<Func<T,object>> expression); 
} 

public class MyRepository : IRepository 
{ 
    public T Find<T>(Expression<Func<T,object>> expression) where T : class 
    { 
    //Implement your caching/ calling your web service here 
    } 
} 

Vous pouvez alors appeler votre dépôt comme ceci:

MyRepository repository = new MyRepository(); 
var model = repository.Find<MyModel>(a=> a.Prop1 == 5); 

Si vous voulez ne pas permettre à l'utilisateur de mettre tout type de type int l'argument générique, vous pouvez avoir vos modèles héritons tous de une classe de base ou impelement une interface et ensuite changer la méthode de recherche à:

public T Find<T>(Expression<Func<T,object>> expression) where T : IMyModelInterface //or whatever base class you want 
+0

Merci Jose. Je n'ai pas utilisé LINQ auparavant. Ma question serait maintenant traduite si j'utilise LINQ Expression en tant que paramètre de la fonction Find alors comment puis-je transformer cette expression en paramètres que la méthode de service Web nécessite? Expression va certainement aider pour ma mémoire cache/collecte de données, mais ma question principale portait sur l'appel de scénario de service Web. – byte

+0

Je pense que le plus simple serait que le webservice prenne aussi un arbre d'expression en paramètre, implémente un IQueryable dans le service web (ie Linq To SQL) et puis nourrit l'expression dans le service web et ensuite Il ne faut pas faire de l'analyse, juste refiler l'argent. :) – Jose

+0

Merci. Le problème est que je ne peux pas modifier le service Web. Il peut également ne pas être un service Web .NET (peut être Java ou C++ sous Unix). Donc le WebMethod serait quelque chose comme chaîne FindMembers (chaîne de nom, int minAge, chaîne de ville) où le type de retour est XML comme chaîne – byte