Design patterns
Repository
Recherche…
Remarques
A propos de l'implémentation de IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter)
: L'idée est d'utiliser des expressions comme i => x.id == 17
pour écrire des requêtes génériques. C'est un moyen d'interroger des données sans utiliser le langage de requête spécifique de votre technologie. L'implémentation est plutôt étendue, vous pouvez donc envisager d'autres alternatives, comme des méthodes spécifiques sur vos référentiels implémentés: Un CompanyRepository
imaginaire pourrait fournir la méthode GetByName(string name)
.
Référentiels en lecture seule (C #)
Un modèle de référentiel peut être utilisé pour encapsuler un code spécifique au stockage de données dans des composants désignés. La partie de votre application qui nécessite les données ne fonctionnera qu'avec les référentiels. Vous souhaiterez créer un référentiel pour chaque combinaison d'éléments que vous stockez et votre technologie de base de données.
Les référentiels en lecture seule peuvent être utilisés pour créer des référentiels non autorisés à manipuler des données.
Les interfaces
public interface IReadOnlyRepository<TEntity, TKey> : IRepository
{
IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter);
TEntity Get(TKey id);
}
public interface IRepository<TEntity, TKey> : IReadOnlyRepository<TEntity, TKey>
{
TKey Add(TEntity entity);
bool Delete(TKey id);
TEntity Update(TKey id, TEntity entity);
}
Un exemple d'implémentation utilisant ElasticSearch comme technologie (avec NEST)
public abstract class ElasticReadRepository<TModel> : IReadOnlyRepository<TModel, string>
where TModel : class
{
protected ElasticClient Client;
public ElasticReadRepository()
{
Client = Connect();
}
protected abstract ElasticClient Connect();
public TModel Get(string id)
{
return Client.Get<TModel>(id).Source;
}
public IEnumerable<TModel> Get(Expression<Func<TModel, bool>> filter)
{
/* To much code for this example */
throw new NotImplementedException();
}
}
public abstract class ElasticRepository<TModel>
: ElasticReadRepository<TModel>, IRepository<TModel, string>
where TModel : class
{
public string Add(TModel entity)
{
return Client.Index(entity).Id;
}
public bool Delete(string id)
{
return Client.Delete<TModel>(id).Found;
}
public TModel Update(string id, TModel entity)
{
return Connector.Client.Update<TModel>(
id,
update => update.Doc(entity)
).Get.Source;
}
}
Grâce à cette implémentation, vous pouvez désormais créer des référentiels spécifiques pour les éléments que vous souhaitez stocker ou accéder. Lors de l'utilisation de la recherche élastique, il est courant que certains composants ne lisent que les données, il convient donc d'utiliser des référentiels en lecture seule.
Modèle de référentiel utilisant Entity Framework (C #)
Interface de référentiel;
public interface IRepository<T>
{
void Insert(T entity);
void Insert(ICollection<T> entities);
void Delete(T entity);
void Delete(ICollection<T> entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
}
Référentiel générique;
public class Repository<T> : IRepository<T> where T : class
{
protected DbSet<T> DbSet;
public Repository(DbContext dataContext)
{
DbSet = dataContext.Set<T>();
}
public void Insert(T entity)
{
DbSet.Add(entity);
}
public void Insert(ICollection<T> entities)
{
DbSet.AddRange(entities);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
public void Delete(ICollection<T> entities)
{
DbSet.RemoveRange(entities);
}
public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public IQueryable<T> GetAll()
{
return DbSet;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
}
Exemple d'utilisation d'une classe d'hôtel de démonstration;
var db = new DatabaseContext();
var hotelRepo = new Repository<Hotel>(db);
var hotel = new Hotel("Hotel 1", "42 Wallaby Way, Sydney");
hotelRepo.Insert(hotel);
db.SaveChanges();