Clean solution (project) structure with EF, Repositories, Entities - asp.net-mvc

I like to keep the structure of the project as clean as possible.
Sample:
--BlogApp.sln
--BlogApp.Data
BlogModel.edmx (the EF mappings)
Post.cs (I end up having partial classes in here with attributes)
--BlogApp.Domain
--Entities
Post.cs (I would like to have my POCOs here with all its additional logic)
--Repositories
PostsRepository.cs
--BlogApp.Ui
(standard MVC structure)
I end up with mess when using EF as my ORM. Could anybody suggest some "clean" way to structure the project? Or maybe you could suggest some standard project structure that is most commonly used.

My preferred structure is:
Solution
-- Common
- Shared features used accross all layers
- You can also place interfaces for repositories and uow here
-- Entities - shared among DataAccess, Business (and UI in small projects)
- T4 template + partial classes + custom enums
- partial classes can contain methods with domain logic => domain objects
-- DataAccess - all EF dependent code here
- EDMX or code first mapping
- Repositories
- UnitOfWork
-- Business - not every project needs this assembly
- Business services
- Logic like workflows
- DTOs exposed to UI
-- UI
- Controllers
- Views
- ViewModels

Check out this write up on T4 Templates and the Entity Framework. You can write in custom attributes for entity properties generated via EF. I've done this several times, and after figuring out how to do it, it now saves a lot of time. I've tried using partial classes before as you mention, but my EF-generated class ends up overwriting the other with the custom attributes. Perhaps I was doing something wrong, but in any case, I now prefer the T4 template solution because it seems cleaner to me - minimizing on number of classes within a project.
Also, when you update your EF model from DB and the class is regenerated, your custom attributes are still in place. ftw!
ADDED:
By the way, we typically define our model objects within the Data layer to have them mapped/populated by EF's entities. Or (even simpler) use the EF-generated entities all the way through to the UI layer without custom defined POCOs.

Related

Which classes I can use as domain model?

I have created a solution with 4 Layers (4 projects):
Entity Framework Layer (EFL)
Data Access Layer (DAL): all of queries and CRUD operations
Business Logic Layer(BLL): my business terms and calling DAL classes
MVC Layer (MVCL)
I added reference of EFL to all layers and added DAL reference to BLL and reference of BLL to MVCL layer.
My problem is my entity classes that are in EFL layer. I can add a reference of EFL in MVCL and use these classes in controllers and views but what about MVC model if I do that?
I create all the EFL classes in model folder of MVC but I didn’t use MVC model.
I just used EFL class. Is it true? Or maybe I should create some function to convert EFL and MVC model classes to each other and then I just use MVC model classes?
Which architecture is true here?
My problem is my entity classes that are in EFL layer. I can add a reference of EFL in MVCL and use these classes in controllers and views but what about MVC model if I do that?
Create a common library (new project). This project should contain your interfaces and common entity classes (like the models used in EF). This project should have 0 dependencies on your other projects, your other projects can then reference this project. This will you to reuse your entity objects across your layers (if needed) and also allow you to define common interfaces on your services so you can expose those from your layers instead of your concrete implementations.
I just used EFL class. Is it true? Or maybe I should create some function to convert EFL and MVC model classes to each other and then I just use MVC model classes?
Whether or not to use a EF model across your layers and into your top presentation layer depends on the model and how it is used. Some times this is fine especially with very simple models or in a simple project. Other times it is not and you will want to convert the model to something that more closely mirrors how the end actor will be manipulating it (including validation and possible dependencies). It usually situation specific unless you specify some common standard across your solution.

Implementing DAL and BOL

I'm Using MVC 3 and I'm having trouble using Entity Framework so I'm trying to understand what would be the best approach to implement my own DAL.
I manage several main entities in my system: User, Department, Calendar etc...
I'm trying to understand the best practice using this kind of tiered architecture.
Should the DAL implement methods that only return DataTables or DataSets or should it be familiar with the model\ business object (User, Department Calendar etc..)?
Should it hold the classes representing the different models\ business object ?
Where should I place the different repository classes are they part of the DAL as well?
1) Should the DAL implement methods that only return DataTables or DataSets
Absolutely not. DataTables and DataSets are artifacts of the past. DAL methods should take/return your DAL entities. For example if you are using Entity Framework those would be the autogenerated classes that EF created for you. Or if you are using EF Code First those would be the classes you wrote to map to your SQL tables
2) Should it hold the classes representing the different models\ business object ?
As explained in 1) the DAL layer should contain the entities that are mapped to your SQL tables as well as the implementation of the repository interface. The repository interface defines the operations with those entities. Inside the DAL layer you will implement this interface for Entity Framework (if this is what you intend to use). Inside the methods you will use the DataContext to perform the different operations with your entities.
3) Where should I place the different repository classes are they part of the DAL as well?
You should place them in the same assembly as your data access classes.
The ASP.NET MVC application will then consume the DAL layer. Your Controllers will simply take the repository interface as constructor parameter and inside the actions you will call various methods on it. You will then configure the Dependency Injection framework of your choice to inject the specific implementation of this repository interface into the controller. This implementation will be the one specific to Entity Framework.
But no matter what you do, don't forget to define view models inside the ASp.NET MVC application itself. Those could be placed inside the Models folder. The view models are the classes that you will be passing to your views. A typical controller action will use the repository to fetch one or more domain entities, map those entities to a single view model that you have defined for the particular view and finally pass the view model to the view. Of course this works the other way around: a controller action takes a view model as action parameter from a view, maps this view model to one or more domain entities and calls one or more methods from the repository passing those domain entities to them.

Which layer should i place .edmx and generated POCO classes?

This is regarding a layered design with EF DB First model.
So far i have not used Entity Framework before, used only Entities and placed on a different project with Domain/ DTO sub folders. Also referred the same in DataAccessLayer, Business Layer and MVC application and written a code with usual ADO.Net queries and prepared POCOs of my entities. No issues.
Now we are developing an application using Entity Framework DB First model. We choosen this DB First model, as the DB Design is not in our control. It is done by DBA.
I thought of reusing the old simple design here. But not sure where/which layer I should exactly fit the edmx file and the generated POCO classes. I didn't find any samples with layered architecture style uses DBFirst approach.
I referred this. http://aspnetdesignpatterns.codeplex.com But they use NHybernate
Here is the highlevel overview of old design.
Any suggestions on design/samples, please you are welcome.
Edit:
From the below answer, I think the entity framework produces the POCOs we could rename existing Entities/Domain layer to Domain Layer and putting the generated POCO classes there. Also we can simply keep .edmx in DataAccessLayer with the list of IRepository classes that wraps EF for TDD. Does this makes sence? or any valuable points?
Update:
Currently i removed DataAccessLayer and keep only Entities layer which
has a model.edmx file and classes generated by EF and also all
Repository classes implementing IRepository. I refer this into
Business Layer, MVC as well. Am i doing right? I feel like i am doing
a bad design :( Please suggest/help
Because you're unfortunately severely handicapped by the decision to create the database first, you will need to use an Anti-Corruption layer per Eric Evans' Domain-Driven Design.
This is a good solution for what to do when you're given a shitty interface that you absolutely must code against - make an interface wrapped around the DB that behaves the way you want it to. Do not expose any EF classes directly to anything except the anti-corruption layer itself.
Here's a reading example:
public class SomeReadService : ISomeReadService {
public SomeViewModel Load(Guid id) {
using (var dbContext = new DbContext()) {
// Query the DB model, then *map* the EF classes to SomeVieWModel.
// This way you are not exposing the shitty DB model to the outside world.
}
}
}
Here's a writing example:
public class SomeRepository : ISomeRepository {
public SomeDomainObject Load(Guid id) {
using (var dbContext = new DbContext()) {
// Map the EF classes to your domain object. Same idea as before.
}
}
}
I would still try to demonstrate to the client that having a separate team design the DB will be a disaster (and my experience strongly indicates that it will). See if there is some way you can provide the feedback that will demonstrate to the client that it would be better if you designed the DB.
Please see the SO link for similar kind of question below:
With a database-first approach, how do I separate my Core and Infrastructure layers?
Hope this helps !!
In my opinion, Entity Framework used correctly negates the need for a seperate DAL. I think of EF as my DAL. It allows you to concentrate on the business part more. EF does all the data access code for you. You can simply use your EF context in your business layer. To me, this is one of the best benefits of EF; that it is your DAL.
Depending on how you separate your layers (different assemblies or different folders within an assembly) depends where you put your POCO classes. If different assemblies (which is overkill for most projects) then a 'Common' assembly referenced by all others is the place to put POCO classes. If different folders, then a folder named 'Models' or 'DomainModels' is the place.
Specifically for an MVC application, I would put my POCO classes in the 'Models' folder (I also have a 'ViewModels' folder), and my .Edmx in a BLL folder which I sometimes call 'Logic'.
If you need a loosely coupled architecture for testing, then a folder named Repositories with the EF context wrapped in your own repository pattern is the way to go.
Edit:
The Short Answer is Data Access Layer (DAL)
You need to Enterprise architecture and it changes according your needs, but in your case Model Driving Design Pattern is the solid solution.
You can use MVC and you can drive your model from Poco or other entities like NHibernet etc.
No any importance about code-first or db-first, it is interesting just with the architecture creation phase.

Where to put data manipulation and business logic code in ASP.NET MVC application?

Having watched samples from Rob Conery's Kona application, I see that he is using two things with IoC - ISession, where he has data layer code and Services, where he has some additional business logic that we need to perform when manipulating data in datastore. For instance, we might not just add a record to the DB but also change properties of another record, increase some counts, take something back, etc. We need to put that additional code somewehere and he puts it in those services.
For instance, he has a CustomerService that manipulates Customers. This requires us to send ISession instance to the CustomerService, so that the CustomerService can use it to access the datastore.
Now another way of doing it would be to put that additional code in the Customer class itself and send the ISession (or IRepository, whatever terminology we use) to that class. And not have any services. Typically, Customer, Order, Product, etc. classes are Model classes, so that would result in big/heavy model classes.
My question is, which solution is better? So far I did not have the need for that because I had most of the code in the controllers but now as my application grows, I need to make a decision on this and cleanup the controllers.
Currently I have:
- fat controllers with business logic in it,
- very atomic repositories,
- very clean models and viewmodels.
Should I move to:
- slim controllers,
- repositories with more code,
- models with business logic code (specifically should my model classes contain methods like Add(), Remove(), for instance Customer.Remove()??)
or to
- slim controllers,
- atomic repositories,
- still clean models,
- services (to encapsulate everything else that does not go into any of the previous).
I would recommend you having repositories containing atomic operations with the model classes and service layer which depends on those repositories to define business operations. The concept of AOP could be used to automatically start a SQL transaction at the beginning of each business operation and commit at the end or rollback in case of exception.
Finally controllers will use those service classes and convert between the domain models and view models.

MVC + Repository Pattern - Still depends on Data Model?

I've started a project for school in which I am using ASP.NET MVC 2 + LINQ2SQL, and a business layer so my UI doesnt interact with the DB directly. My question is this:
In my MVC project, when bringing up views and passing around data, I still have to include my Data project for access to the classes in my Linq2Sql project. Is this correct?
Example:
Controller:
ClassesRepository cr = new ClassesRepository(); // this is from my Business project
Class classToEdit = cr.GetByClassId(id); // "Class" is from my data project
I still have to reference the Class class in my linq2sql data project - shouldn't my UI be completely independent of my data layer? Or maybe I'm going about this all wrong.
I prefer to have my Repository do the mapping internally to my own classes. So what I return from my repository is not the LinqToSql classes but my own. I then map the returned classes data into a model for each views.
So it looks like:
LinqToSQL class -> MyClass (output from Repository at this point) -> (controller maps to model for a specific view) MyModel.
Make sure to always make a model for each view. You can just use what your repository returns but that is a short cut and mapping it to their own view models will pay off in the future.
Take a look at the Golf Tracker Series at MVC Central, it does what you want and what Kelsey is describing.
http://www.mvccentral.net

Resources