J'ai presque terminé l'implémentation de mon modèle de référentiel en ayant une interface IRepository<T>
, une classe NewsRepository
et une entité News
. Le problème que j'ai rencontré était d'essayer d'extraire des méthodes communes à une classe Repository de base.Comment implémenter Repository Pattern avec interface, base et béton
Je ne pouvais pas trouver un moyen de résumer la méthode Get dans le NewsRepository
car il contient une expression Linq spécifique.
Mes questions sont:
1) Comment puis-je abstrait à une classe de base la méthode public T Get(int id)
s'il vous plaît? La seule façon de le faire est de passer en Expression<Func<T,bool>>
au lieu d'un int, mais cela ne fait pas vraiment abstraction du comportement commun car chaque sous-classe devra toujours passer dans une expression presque identique dans chaque cas. c'est-à-dire n => n.id == id
.
2) Comment passer I dans la classe de base sur la méthode de mise à jour des GetViolations sous-classe et les méthodes de carte s'il vous plaît? J'imagine la solution est probablement en utilisant des délégués, mais je ne pouvais pas obtenir la syntaxe pour compiler
Ceci est un ensemble simplifié du code - en pratique, j'ai une méthode Save qui met à jour et insérer plutôt que seulement la mise à jour montré ici.
public interface IRepository<T>
{
T Get(int id);
void Update(T item);
}
public class NewsRepository : IRepository<News>
{
private Table<News> _newsTable;
public NewsRepository(string connectionString)
{
_newsTable = new DataContext(connectionString).GetTable<News>();
}
public News Get(int id)
{
return _newsTable.SingleOrDefault(n => n.NewsId == id);
}
public void Update(News item)
{
var errors = item.GetRuleViolations();
if (errors.Count > 0)
throw new RuleException(errors);
News dbNews = _newsTable.SingleOrDefault(n => n.NewsId == item.NewsId);
map(dbNews, item);
_newsTable.Context.SubmitChanges();
}
private void map(News dbNews, News news)
{
dbNews.Title = news.Title;
dbNews.Article = news.Article;
}
}
public class Repository<T> where T : class
{
protected Table<T> _table;
public Repository(Table<T> t)
{
_table = t;
}
//How do i do this??! - This doesn't compile due to T no having a NewsId
public T Get(int id)
{
return _table.SingleOrDefault(n => n.NewsId == id);
}
//This seems to be a solution, but it's not really abstracting common behaviour as each
//sub-class will still need to pass in the same linq expression...
public T Get(Expression<Func<T,bool>> ex)
{
return _table.SingleOrDefault(ex);
}
public void Update(T item)
{
//How is it possible to pass in the GetRuleViolations and map functions to this method?
var errors = item.GetRuleViolations();
if (errors.Count > 0)
throw new RuleException(errors);
T dbNews = _table.SingleOrDefault(n => n.NewsId == item.NewsId);
map(dbNews, item);
_table.Context.SubmitChanges();
}
}