locked
Repository pattern -- pros and cons? RRS feed

  • Question

  • User1168500272 posted

    This is possibly the worst kind of religious debate -- a religious debate with practical consequences.

    But it's one that needs to be had, and I can't seem to fit it in my tiny head, so I need some help.


    Here are the pros and cons of the pattern as I know them:

    Pros:

    -Encourages DRY (don't repeat yourself) design in that identical queries are written only once per set of query conditions

    -Facilitates unit testing by allowing itself to be abstracted into an interface

    -Creates an opportunity for business-level validation

    Cons:

    -Breaks DRY philosophy in that you're generally repeating your database schema

    -In a sense breaks separation of concerns, because the query concerns of the controller and view frequently become the concerns of whoever is maintaining the repository

    -Determining what should be a repository and what should be returned as a raw associated ORM entity becomes an ambiguous art


    I hope I'm wrong on some of these points; it would help me make a decision. Please let me know.

    To me it seems like all this stuff should be done at the ORM level, but Entity Framework has much fewer hooks than Linq to Sql does, yet Entity Framework tends to be regarded as being more robust, so it seems that this is by design, and that the designers of EF are in fact encouraging another layer.

    Are there any tools or anything that I could be using for this? Am I missing something?


    Thanks in advance,

    Rei

    Thursday, July 8, 2010 2:31 PM

Answers

  • User1314135081 posted

    I'm almost always use a repository to manage storage issues. It abstracts the db very well and best of all, it allows you to design your application as if there is no db involved.

    In the application I'm developing now, I'm using both linq2sql and ado.net to manage db stuff but the rest of the application doesn't know or care about that (and that's the most important part). I'm returning DTOs usually which are domain DTOs not linq2sql entities. Of course sometimes it's easier to return directly a linq2sql object but in those cases I'm returning an interface defined in the domain assembly.

    Use the Repository to abstract away anything related to persistance implementation, it doesn't matter you're using linq2sql, EF, ado. net etc and have your Repository methods return interfaces defined at the domain layer instead of ORM objects or whatever data access object you're using. This way, the business layer is decoupled from the storage layer and you can keep things tidy.



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, July 11, 2010 5:23 AM

All replies

  • User653228039 posted

    First of all, Repository Pattern is conceptually separate from Linq vs Entity.  You could use Repository to manage data from all sorts of sources, whether they be entity, linq, ADO.NET, file system data storage, xml, webservices, whatever.  A repository is simply a collection of methods that return usable data objects and abstract the business layer from the data layer.  That said, your assumption that Repository breaks DRY isn't exactly accurate.  It all depends on how you implement your repositories.  A repository doesn't have to be a one-to-one match to your database tables.  You could have a repository that deals with users and makes calls on UserAccount, UserProfile, UserHistory and a whole bunch of other tables.  The point is that Repository should return usable chunks of data that your business layer needs while eliminating the need to constantly write the same queries over and over.  The benefit to this is that should your data source change, your business layer can remain unchanged, and the only thing that really needs to be rewritten is the repositories.  You make an interesting point that separation of concerns are a little blurred, and while that might be true, that initial investment in work creating the repository helps separate those concerns better in the long run.  As I said before, the Repository is really there to make the business logic more agnostic to how the actual data source is structured.


    One trouble I've come across using Repository Pattern is in dealing with the various data contexts.  You have to really be paying attention in business layer where your data came from.  And it is in this sense that the separation of concerns aren't totally separate.  But in all honesty, once I started coming across these problems, I determined that it really is a matter of unfamiliarity, and once I discovered it, I was more in tune with ensuring my data context management was better.


    Thursday, July 8, 2010 6:51 PM
  • User1168500272 posted

    Thanks, I'll give the pattern some more thought.

    I'm still unsure on some of the details of how I'd implement it, but now I have a clearer idea of what the purpose is.

    Friday, July 9, 2010 4:13 AM
  • User653228039 posted

    Take a look at the Nerd Dinner tutorial:

    http://nerddinnerbook.s3.amazonaws.com/Part3.htm

    I used this to learn what MVC was all about, but also ended up learning about Repository Pattern as well.  The developer in this tutorial uses Linq to Sql with a Repository class to help development.  There are many pages, but the 3rd page I linked you to is where he starts discussing the Repository Pattern.

    Friday, July 9, 2010 12:29 PM
  • User1168500272 posted

    Yeah, that's where I first learned about the repository pattern too. It doesn't use the Entity Framework though, at least not in the article. The sample code that you can download is updated to use EF.

    I still get this horrible nagging feeling that EF should at least partially solve the problems that the Repository pattern solves. From the way people describe it, EF isn't an ORM; it's supposed to be a conceptual entity-relational model, so it seems like I should be able to model business interactions with it.

    As far as consolidating query code goes, this to me seems sufficient (and much more testable):

    public static IQueryable<Post> WherePostIsLive(this IQueryable<Post> q)
    {
        return q.Where(x => DateTime.Now >= x.PublishTime && x.IsDraft == false);
    }

    The only downside I can think of to this approach is that I or someone else might forget to make this constraint. The Repository pattern doesn't necessarily fix that problem either though, since one can just as easily make an unconstrained query via an association -- even if a repository query doesn't itself return an IQueryable.

    Saturday, July 10, 2010 7:24 PM
  • User1314135081 posted

    I'm almost always use a repository to manage storage issues. It abstracts the db very well and best of all, it allows you to design your application as if there is no db involved.

    In the application I'm developing now, I'm using both linq2sql and ado.net to manage db stuff but the rest of the application doesn't know or care about that (and that's the most important part). I'm returning DTOs usually which are domain DTOs not linq2sql entities. Of course sometimes it's easier to return directly a linq2sql object but in those cases I'm returning an interface defined in the domain assembly.

    Use the Repository to abstract away anything related to persistance implementation, it doesn't matter you're using linq2sql, EF, ado. net etc and have your Repository methods return interfaces defined at the domain layer instead of ORM objects or whatever data access object you're using. This way, the business layer is decoupled from the storage layer and you can keep things tidy.



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, July 11, 2010 5:23 AM
  • User1945922531 posted

    Thanks, I'll give the pattern some more thought.

    I'm still unsure on some of the details of how I'd implement it, but now I have a clearer idea of what the purpose is.

    Hi, some example of implementation simple Repository with Linq To SQL you can check out here:

    http://abeletsky.blogspot.com/2010/06/ddd-implementation-of-repository.html

    Also, not so long time ago such kind of question is alreay came up:

    http://forums.asp.net/t/1572255.aspx

    Sunday, July 11, 2010 1:55 PM