1

So, for the first big project that I'm getting paid for, I decided I'd do things right.

To that end, I've created several projects in my Solution. Some of these projects are generic and handle common elements that can be used in any project (stuff like logging and such), but that's not where the focus of my question is.

The projects I'm concerning myself with in this case are mostly to do with the database and the actual web application that will use it.

So I have an Ortund.Objects Class Library Project and an Ortund.DBContext Class Library Project.

Ortund.Objects
This project defines the classes, setting properties and default values that makes up the database.
For example, the Users class defines properties such as Username, EmailAddress, Password

Ortund.DBContext
This project uses Entity Framework and the Objects project to build the database. DbSets of the classes in the Objects project and various other components explicitly define the structure of the database.

Obviously, given this structure, I would have the DBContext project referencing the Objects project. This means that, while somewhere in my head, it makes sense to put all my methods and functions that the web app will use into the Objects project, I wouldn't actually be able to do anything because I won't have the DbContext. To reference the DBContext project would create a circular reference.

So, in order for my application to interact with the database now, the only option I can see is to create a 4th project to act as the data layer, effectively becoming a "middle-man" between the web application and the other 2 projects.

When I suggested this on IRC, someone answered with the following:

No, the application layer uses the database layer to provide persistence to the domain layer.

I don't understand what this means. Can someone help me to understand how best to structure this application?

1

1 Answer 1

2

A typical full-tier application can be composed in many different ways. One of those ways is very similar to what you have come up with so far. The layers go somewhat like this (feel free to tweak and extend as per your use case):

  1. A Models layer, which contains your database objects. These classes map directly to your database.

  2. A Data Access layer, which contains your entity framework code and uses (1) to provide CRUD operations, etc.

  3. A Business Logic or Domain layer, which uses (2) and adds business logic, domain-specific rules and functions to the mix

  4. Sometimes, this business tier defines its own Domain Objects. These are also model objects, but they are in the context of the end-user rather than that of the database. A single business-tier object may be a logical composition/transformation of multiple database model objects.

  5. Finally, an Application layer, which exposes a specific UI for a specific consumer. It uses the underlying business tier functions to do the actual work.

It is not necessary for these layers to be in separate packages. It all depends on the complexity and size of your application. The loose coupling helps to separate out the layers into independent modules as and when the need arises.

7
  • So if I understand you, that means my code for login, getting listings (GetUsers(), GetUserById(int UserId), etc) go into what is, at this point, my DBContext project?
    – Ortund
    May 21, 2014 at 10:49
  • and then business logic (calculating change on purchases and stuff) would go into a separate project?
    – Ortund
    May 21, 2014 at 10:50
  • Is it a direct database query? Then it probably goes to the Data Access layer which I guess is your DBContext project. And for your second comment, yes that is business logic, which goes into a separate package. Whether it is a whole separate project is up to you :) You can always separate later as long as you make sure that each layer only uses the packages it is supposed to and is cleanly separated out.
    – metacubed
    May 21, 2014 at 10:57
  • To give you some idea, GetUsers() would look something like this... public List<User> GetUsers() { return db.Users.Include(r => r.Role).ToList(); }
    – Ortund
    May 21, 2014 at 11:13
  • Yes that seems appropriate as a Data Access layer query.
    – metacubed
    May 21, 2014 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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