Real World ASP.NET MVC Repositories
Asked Answered
R

3

8

In the real world, Controllers can potentially need to use data from a variety of database tables and other data stores. For example:

[Authorize]
    public class MembersController : Controller
    {
        ICourseRepository repCourse;
        IUserCourseRepository repUserCourse;
        IMember member;
        public MembersController(ICourseRepository repCourse, IUserCourseRepository repUserCourse, IMember member)
        {
            this.repCourse = repCourse;
            this.repUserCourse = repUserCourse;
            this.member = member;
        }

So:

  1. Should I use a repository for each table?

  2. I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?

  3. Do I just add as many Repositories as I need to the constructor of the Controller?

  4. Is this a sign that my design is wrong?

NOTE:

The IMember interface essentially represents a helper object that puts a nice face on the Membership provider. Ie, it puts all the code in one place. For example:

        Guid userId;
        public Guid UserId
        {
            get
            {
                if (userId == null)
                {
                    try
                    {
                        userId = (Guid) Membership.GetUser().ProviderUserKey;
                    }
                    catch { }
                }
                return userId;
            }
        }

One problem with that is surely caching this kind of output. I can feel another question coming on.

EDIT:

I'm using Ninject for DI and am pretty sold on the whole DI, DDD and TDD thing. Well, sort of. I also try to be a pragmatist...

Ratsbane answered 24/11, 2010 at 17:18 Comment(3)
possible duplicate of Repository pattern: One repository class for each entity? - This pops up every month or so.Select
@jfar - so you vote to close something for a duplicate, then you post your exact same answer you had in that duplicate question (word for word) here? How does that work??Tasse
@Tasse - Because dupes are rarely closed anymore and I didn't want qstarins answer to be the only one in this question.Select
M
6

1. Should I use a repository for each table?

Probably not. If you have a repository per table, you are essentially doing Active Record. I also personally prefer to avoid calling these classes "Repository" because of the confusion that can occur between Domain Driven Design's concept of a "Repository" and the class-per-table "Repository" that seems to have become commonly used with Linq2SQL, SubSonic, etc. and many MVC tutorials.

2. I guess this is where the concept of agregates comes into play? Should I have one Repository per aggregate?

Yes and yes. If you are going to go this route.

'3.' Do I just add as many Repositories as I need to the constructor of the Controller?

I don't let my controllers touch my repositories directly. And I don't let my Views touch my domain classes directly, either.

Instead, my controllers have Query classes that are responsible for returning View Models. The Query classes reference whatever repositories (or other sources of data) they need to compile the View Model.

Mantel answered 24/11, 2010 at 17:49 Comment(6)
Issue with #1. Repositories abstract your ORM away from you and provide a much more testable interface than going direct against a datacontext/nhib-session. These classes are not pointless and can encompass persistence specific logic like updating "last updated".Select
@qstarin I have a similar setup except we access repositories through domain services instead.Foxy
@jfar: "pointless" is a bit strong. But those concerns don't need a "repository" specifically, and I find it worth avoiding the potential confusion with DDD's concept of what a "repository" is. I tend to call them DAO's if they are per-table data access objects. Also, if you are doing repository per table, you aren't really using an ORM. Well, you may technically be using an ORM, but not utilizing the M part.Mantel
@qstarin - Repository has nothing to do with DDD. Its a pattern that can live on its own. And your completely wrong with ORM part. Thats still mapping and loading nested/related entities is still a huge part of ORM. I think your trying to paint a bad picture of "unless your using DDD your being primitive".Select
@qstarin gets the biscuit cos his answer points in the right direction. It sheds light on why a service layer is a good idea.Ratsbane
@jfar: It is not my intention to paint a bad picture of "unless your using DDD." Not at all. However, referencing Fowler from PoEAA: "[A Repository] Mediates between the domain and data mapping layers" (emphasis added). What you are talking about is the data mapping layer, imo. My opinion on this grew out of seeing much pain experienced by getting not-DDD & DDD confused in projects that did both poorly.Mantel
R
2

Well @awrigley, here is my advise:

Q: Should I use a repository for each table?

A: No, as you mentioned on question 2. use a repository per aggregate and perform the operations on aggregate root only.

Q: Do I just add as many Repositories as I need to the constructor of the Controller?

A: I guess you´re using IoC and constructor-injection, well, in this case, make sure you only pass real dependencies. this post may help you decide on this topic.

(pst! that empty catch is not a nice thing!!) ;)

Cheers!

Readership answered 24/11, 2010 at 17:57 Comment(1)
empty catch = still under development and = future bug!Ratsbane
S
-1

This all depends on how "Domain Driven Design" your going to be. Do you know what an Aggregate Root is? Most of the time a generically typed repository that can do all your basic CRUD will suffice. Its only when you start having thick models with context and boundaries that this starts to matter.

Select answered 24/11, 2010 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.