0

I've seen some tutorials and examples of implementing a repository pattern, and I don't quite understand something. My impression was that the whole point of a repository pattern was to hide the underlying data storage implementation from the calling code. Am I wrong in this assumption, in which case, what is the point of a repository pattern?

Assuming repositories are meant to hide the underlying implementation, am I right in thinking that implementations like the following EF implementation are leaking EF implementation details and are therefore incorrect repository implementations?

public interface IRepository<TEntity> where TEntity : class
{
    TEntity Get(int id);
    IEnumerable<TEntity> GetAll();
    IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);

    // This method was not in the videos, but I thought it would be useful to add.
    TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate);

    void Add(TEntity entity);
    void AddRange(IEnumerable<TEntity> entities);

    void Remove(TEntity entity);
    void RemoveRange(IEnumerable<TEntity> entities);
}

As I see it, this leaks the fact that EF entities are being used to store and retrieve data from the DB as TEntity is passed in and returned to and from methods. I'd have thought you'd need to define POCOs, pass them in to the repo, then map then to TEntitys to be correct. Even more leaky is the Expression<Func<TEntity, bool>> predicate lambda, which not only leaks TEntity again but assumes that the underlying implementation implements EF-style .Where() LINQ queries on datasets. This just seems like it's not decoupled from EF.

Am I misunderstanding the purpose of a repository or are my criticisms valid here?

  • 4
    Other than the fact that TEntity has the word 'Entity' in it, what makes you feel that Entity Framework details are being leaked here? The way the code is written, TEntity can be any class, and implementors of IRepository can use any data access mechanism they want; it doesn't have to be EF. – Eric King Mar 28 at 18:36
  • Well OK on that point. Although in his actual implementation he does just pass EF entities through to EF, suggesting that was his thinking. Also, my point about the lambda stands. – Jez Mar 28 at 18:45
  • The lambda point is also not an EF thing... LINQ is independent of EF and is used in many places that have nothing to do with EF. Try this: replace the arbitrarily named TEntity in your code example with just T. The functionality would not change, but it would be clearer that the IRepository interface is generic and not EF-specific at all. Now, if you are just going to use it to pass EF entities back and forth, that's a different issue. But the IRepository interface itself is agnostic of what kind of class T is, and doesn't leak actual implementation details that I can see. – Eric King Mar 28 at 18:52
  • Presumably there'd be no way to design the interface to prevent it passing EF entities back and forth? Therefore it would be possible to implement this interface with a class that was supposed to take EF entities, or even domain objects, and DTOs? – Jez Mar 28 at 18:55
  • Well, the way it's written where TEntity : class explicitly allows TEntity to represent any class, including EF classes or POCOs or whatever. If you want to limit what kind of class is handled by the interface, change it to where TEntity : somethingelse – Eric King Mar 28 at 18:57
3

There is absolutely nothing in that interface that leaks the details of the implementation. Without issues you can implement a concrete class with EF, or Dapper, or even MongoDB or whatever you want.

You would have an argument if that interface had some sort of SaveChanges() method or some other pattern or requirement that was essentially driven by EF and not very relevant to other implementations. As it stands, the interface doesn't really suggest anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.