6

I want to create an asp.net application which has several layers (classic layer design): A business layer and a presentation layer. Data layer seems obsolete as EF does all the work.

So when I create the EF model in Business Layer, I cannot use the entities in presentation layer because I can't add data annotations for display and validation and so on (especially display attribute is typically a part of presentation layer). And it seems not very good to me to create copy all the data to similar "viewmodel"-classes in presentation layer.

So is there a good approach to create object context in business layer and having a shared "contracts"-assembly for the entities? Most samples that I have found place everything in one single assembly, which is not the best approach for more complex applications in my opinion.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Martin H.
  • 1,086
  • 1
  • 17
  • 28
  • 2
    View models are the way to go. Might not seem very good to you but it's the right approach. – Darin Dimitrov Oct 01 '13 at 06:30
  • 2
    EF **IS** your data layer. You should build it so it doesnt creep into your business layer. What if your boss says "STOP ALL EF WORK! WE HAVE TO SWITCH TO NHIBERNATE CAUSE MY NEPHEW SAYS IT RULES!"? – crthompson Oct 01 '13 at 06:34
  • 3
    @paqogomez - Fire your boss? – Erik Funkenbusch Oct 01 '13 at 07:42
  • My hope was to save all the writing work and the runtime data copying. And yes, I used this approach in the past EF and view models. – Martin H. Oct 03 '13 at 10:02
  • My hope was to save all the writing work and the runtime data copying. And yes, I used this approach in the past: EF and view models. But in my last project I realized e.g in administration part of my application most of the view models are very identical to all the EF model classes and I had a lot of writing work just to map models which only have id and name plus eventually a flag. Thanks for the reply to all of you. It seems to me I did everything right in the past, when planning layered applications. – Martin H. Oct 03 '13 at 10:10

4 Answers4

5

You should abstract EF away from your business layer, never use such frameworks directly. I usually create a generic repository interface and a generic EF repository (this is your data layer) which implements the interface. An IoC framework will take care of the injection of the right implementation at runtime.

Also, you are exactly describing the need of ViewModels in your presentation layer. They take care of showing only the information you need on the view along with the validation based on the data annotations. In the beginning they might look like duplicates of your domain entities, but in the end it will save you a lot of trouble, it's definitively the way to go.

Your business layer should result domain entities, in your controller you map them to your ViewModels. You could use AutoMapper for this.

You can check out this question and answer for more information about service/business layers and domain/view models.

Community
  • 1
  • 1
Henk Mollema
  • 44,194
  • 12
  • 93
  • 104
  • Ok, so this is just the approach I also easy used. EF, view models, mapping and IOC. I just hoped to avoid writing work at design time and data copying at runtime. Thanks for the reply – Martin H. Oct 03 '13 at 10:21
  • @MartinH. I always end up with ViewModels completely different than my domain models. Usually they are a combination of properties from multiple domain models etc. But yes, sometimes they are almost identical, except for the data annotations.. I also mentioned AutoMapper, this saves you the daunting task of manually mapping the domain models to ViewModels. – Henk Mollema Oct 03 '13 at 10:37
2

You can have layers like this.

  1. EF model layer project
  2. Business layer, which will interact with EF model
  3. Presentation layer, which interact with business layer, and you can give reference to EF model too, if needed

You can create your partial classes in EF model layer - for data annotation and all. So it can in turn - will be used in business layer also.

Paritosh
  • 11,144
  • 5
  • 56
  • 74
  • Yes, but data annotations (especially display attribute) is part of the presentation layer in my opinion and I only can add attributes in the project where the EF model is defined. – Martin H. Oct 03 '13 at 10:12
1

Create Data Transformation Objects (DTOs) that are exact copies of your Entities, except they only have the simple properties. Then use automapper to map between Entities and DTOs.

MrShoes
  • 485
  • 10
  • 28
0

Here i have a good suggestion for you.

first of all divide you application in Layers

**SM.MVCApp**  :-  This is for MVC application 
**SM.Service** :- This layer is for holding the business logic (Interface & Class)
**SM.Data**    :- This layer is to interact with database using Entity framework (Repository & UOW)  
**SM.Entity**  :- This layer is responsible for having property in class that will be mapping with the table of database.

SM.Service example

public interface IStudent
{
    IQueryable<Entity.Student> GetAllStudent();

    Student GetStudentByID(Int32 StudentID);

    void CreateStudent(Student objStudent);

    void UpdateStudent(Student objStudent);

    void DeleteStudentvoid(Student objStudent);

    void SaveChanges();

    List<Entity.Student> SearchStudent(string Name, int Age, string EmailAddress, string CountryName);

    void MakeRelation(Entity.StudentCourceMap objMap);
}

Now showing How to create SM.Data Layer

  1. First of all Create DBContext class for creating database and tables
  2. Then create IRepository * Repository class for crud operations
  3. Then create UOW (Unit of work)
DK Chauhan
  • 194
  • 1
  • 11
  • Thanks, but I tried repository and UOW, but in complex situations it's not very useful (or I implemented it wrong). – Martin H. Oct 03 '13 at 10:14
  • To clarify: your student example works when getting the students. But when I have a student object, want to know his timetable, want to know his results, I'm creating repositories for every linked table (and I know applications with hundreds of tables). And if I had EF model I could go further directly. – Martin H. Oct 03 '13 at 10:18
  • In that case you can use "joins" – DK Chauhan Oct 03 '13 at 11:18