WPF MVVM - Repository pattern query
I have a web service which provides an interface to query data. I am writing a WPF application using MVVM. I am working on creating a repository that my View Models can use to retrieve models. The repository will call the Web service to fetch data, when required.
I would require various Find methods in my repository that finds the data based on various criteria and not just one criteria like 'Id'.
In my Repository, I have created a Find method that takes a Specification as input
void IList<MyData> Find (ISpecification spec)
where a basic ISpecification interface is
public interface ISpecification<T>
{
bool IsSatisfiedBy(T candidate);
}
A high level implemenation of the Find method would be as follows
- first searches the cache for candidates that satisfy specification
- If found return the list of candidates
- Else use the specification / criteria to call web service to fetch the candidates and return the list
I am confused about the Else scenario above - What is the correct way of designing the Specification so that if I have no data in repository cache that satisfies the specification, I should be able to retrieve the criteria from specification and call the web service passing the web method this criteria?
A few things on my mind-
- If I specialize Find methods to take specialized specifications which have properties / criterias then Repository开发者_运维知识库 - Specification has tight coupling
- If I would have to connect directly to DB (which I am not) then I could have supported a method that returns an SQL for example. LINQ could have been an option etc
Why don't you use a linq expression as the parameter input?
e.g.
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
}
}
So you could then call your repository like so:
MyRepository repository = new MyRepository();
var model = repository.Find<MyModel>(a=> a.Prop1 == 5);
If you want to not allow the user to put any kind of type int the generic argument you could have your models all inherit from a base class or impelement an interface and then change the find method to:
public T Find<T>(Expression<Func<T,object>> expression) where T : IMyModelInterface //or whatever base class you want
精彩评论