I am an experienced .NET developer who has primarily been working with webforms. I am familiar with MVC but have not used it commercially yet. I am currently conducting some self-education in this area and am somewhat confused by the differences in opinion on the subject of architecture, let me prefix this question with the understanding that there is not a right or wrong answer but I am simply seeking what is an elegant solution.
I will start out by saying that I am not using the entity framework or any sort of ORM – I would like to directly implement my own business objects and data access code (using ADO, SPROCS etc) to ensure they are optimal, this is a personal preference. This is where I am struggling to find consistent information as it appears most information relates to the use of LINQ to SQL or the Entity Framework.
MY application has been structured with the following projects:
- Web (MVC 3 Web application)
- Models (class library)
There are only two projects because I am having issues decoupling things; this is the root of my question.
My model class library contains…
- classic business objects with fields and properties
- A repository class for each business object which contains data access code (ADO.NET straight forward SqlDataReaders etc)
- An interface for each repository class
The issue I have is the dependency between all these layers. It does not feel right at all!
1.The business objects should contain methods that implement the business logic, so aside from the fields and properties there are methods to implement any required logic?
2.The repository classes execute data access code but know about the business objects, this again does not feel right, the data access code should sit in its own class library and know nothing about the objects?
3.The controllers (in the web layer) leverage the repository interfaces but why? They should not contain business logic, the ‘model’ or business object should? The controllers should certainly not contain business logic so again this is not right. I don’t want business logic in repositories as they are hitting the database.
I am struggling to find an elegant architecture for the application, just a basic outline of how to implement my own objects, my own data access code and ensure the application is loosely coupled. Can anyone offer me any guidance please?
I would suggest a few changes to your solution structure.
For example, the projects could be structured as follows:-
Core Library
This would be simple POCO’s that represent your domain data and interfaces to any services. There is no business logic here. Just simple properties.
eg.
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
}
Services
This would be where you contain your business logic. How does a user validate? How do we calculate when a Order should be auto-archived or whatever? Generally, I don’t do any database stuff in here.
Repository
This is where you do your basic database stuff. You said you’re not using L2S or EF, etc. No probs. I would seriously seriously look at using a Micro-ORM instead, like Dapper or Massive.
Tests
You’re doing unit and integration tests, right? i recommend xUnit or nUnit for the testing framework.
Web Application
This is the MVC3 application. I would recommend using StructureMap for your Dependency Injection. (You are using an IoC/DI, right?)
You might think at first -> that’s SOOO many projects, right? well, it’s easy to split this into TWO projects only.
and the Core Library, Services, Repository all exist in the Web Application project as folders.
Try and not over-engineer the Visual Studio solution. Most people think they need lots of projects and crap loads of abstraction .. because that’s what they think everyone else is doing and it’s the right thing. Well, that train of thought is very very early 2000’s .. and in 2012 – lots of shiz has changed since then.
Try using DI/IoJ, NuGet for downloading these libraries into your solution, Micro-OR/M’s for data access and a Testing project.
A few projects to check out, re: how things are layed out :