I'm interested in using entity framework - code first migrations with a new database, and I have some questions/concerns about duplicating POCO code in the data and business layers.
The idea is to have a data access layer containing my POCO entities all decorated with database schema type items like string lengths, foreign key related things that don't work out of the box, and whatever else. This layer will also act as a repository that will return scalar values, entities, aggregates, and IEnumerables.
Above that will be the business layer, which will handle talking to the repository, and a bunch of business logic.
At the top is the presentation layer. This layer talks to the business layer, and has no idea about the data layer – all it understands is view models. I would implement the MVC pattern at this layer, using only view models.
The issue I am running into is related to where I should do the mapping between my view models and my data models. If I define the view models in my presentation layer, the business layer will not know they exist.
Am I better off defining the view models in the business layer, or do I need a set of domain models in the business layer that the presentation layer would be aware of and be able to perform mapping against?
Would an additional set of domain models just be an egregious duplication of the models defined in the data layer?
Depending on the scope of the project, I usually use one of the two methods below:
1) have a set of domain models separately from all layers, and then have all layers reference them.
Pros: layers are still independent, no model duplication, no need to map layer models.
Cons: change in domain model would affect all layers, e.g. DB change may break display
2) have models in each layer. Business layer would map its own models to those of data layer, presentation layer would map its models to those of business layer
Pros: every layer does one thing, changes in underlying models to not propagate through layer
Cons: duplication of the models is likely and mapping needs to be maintained
First approach works best for smaller apps and "direct updates" scenarios, second works better in large projects with multiple moving components.
P.S. "defining the view models in the business layer" is a definite no-no.
Related
we have a classical 3-tier-architecture application. Now we face a little problem and we don't know the best way to handle it.
In the last layer (database-layer) we have a POCO-class, that gets filled with data from a database. In the top layer we have a MVC3 asp.net web-application. The MVC application would work best, if it could just read the POCO-class.
But as the GUI-layer cannot access the database-layer directly, it cannot get the exact same class.
What is the best way to get a POCO-class from the last layer to the top layer?
The actual issue is that your entities should not be defined in the data layer. Data layer, as well as any other layer in your app, might get completely rewritten one day, and you don't want entities themselves to be tied to any of these layers.
In other words, define your entities in a separate project, and then reference it from all other projects:
- Entities
- Data access layer
+ references Entities
- Business layer
+ references DAL
+ references Entities
- Presentation layer
+ references BL
+ references Entities
The same goes for repository interfaces: if you are using a repository pattern to abstract your data access, Entities project is the one which should contain all repository interfaces, which can then be implemented by a specific DAL choice.
You can create a project of DTOs that is referenced from all the different layer projects. This way you can share the DTO POCOs between all the layers of your application.
I am creating a solution from scratch, using ASP.NET Web forms C#.
I am concerned about the model objects as I don't want to create duplicate sets of model objects in each layer. What is the best practice for using Model objects in 3 layer architecture in Web Forms?
The structure I have in mind is as follows:
UI
BLL
DAL
Model
The Model will contain all the model classes that can be used in each section of the layers. I thought this would be useful as each layer needs access to the model objects. For example:
UI calls a method in BLL passing in a model object filled with data.
BLL calls a method in DAL passing through the object which is saved
in the database etc.
Thanks
Models can be a cross-cutting concern with your layers, which is a quick way to do it. Or you can create interfaces for your models such that you could simply flesh out the interface in something like the BLL - this at least stops it being cross-cutting.
It further depends on if your models are simple data containers (anemic domain model), or contain behaviour, such as the ability to validate themselves or track changes themselves (rich domain model).
You can find that your DAL actually consists of two parts: the boilerplate-never-specific to an app code to talk to the database, and the app-specific populate-the-model code. We have this situation. We share interfaces of our models around, the app-specific DAL code can use this interface in order to push and pull data from the model, but the "true" DAL code works with raw stuff.
In a relatively small application, you can share your Domain Entities all the way up to your Presentation layer but be aware of the coupling this introduces.
If in your Databinding you except an Entity of type Customer with a property Address with a StreetLine1 and StreetLine2 property then all your layers are tightly coupled together and a change in one layer will probably cause changes in other layers.
So your decision should be based on the scale of your project and the amount of coupling you can have.
If you go for a low coupled design then your BLL will use your DAL to retrieve entities and use those entities to execute behavior. The BLL will then use Data Transfer Objects to pass to your Presentation layer so there is no coupling between your presentation layer and your Domain Model.
look at my answer here: https://stackoverflow.com/a/7474357/559144 this is the usual way I do things and works well, not only for MVC and Entity Framework... in fact in MVC the model could be an entity type which only has some of the fields contained by the real business entities defined in lower layers, it depends if you really absolutely need all fields in the UI level as well or only some to do some data rendering and input...
As a related topic, please see this related answer which I posted recently on avoiding duplication of code and correct architecture in a cross-platform client/server system.
I have +1'd the other posters in this thread as this is not intended to be a full answer, just useful information related to the question.
Best regards,
I have a three layer architecture program. The questions are:
1. Data access is the layer of EF?
2. If i want to use an entity generated by EF from Presentation Layer, then i reference the Data Access, but this violates the principles of 3 layered architecture.
Microsoft Spain released a pretty good documentation, guide and sample application for N-layered applications on codeplex, you can look it up here:
http://microsoftnlayerapp.codeplex.com/
You will find many directions and helpful implementation patterns there.
hth.
Yes EF would be your Data Access Layer.
With EF you can use T4 templates with POCO support, you can then extract these POCO into a seperate dll and this will be reference from all of your layers.
What type of application are you building? If you are building an ASP.NET MVC 3 application, you can have your View be the presentation layer, your Model is your data access (which can use EF) and the controller and / or Action Filters can contain your business logic and in this scenario you will be using your EF Model in the presentation layer but still satisfy the separation of concerns principle.
EF does two things: -
1) Generates an domain model for you (optional, but commonly used)
2) Gives you the ability to query / modify your database via that domain model.
This can give the appearance of blurring the lines between domain model and data access but the two are indeed separate.
As long as you're not doing stuff like creating object contexts and writing queries directly in your presentation tierthen IMHO you are not breaking abstraction - the only thing you are "breakin"g is the fact that you will need to reference System.Data.Objects (or whatever the EF dll is) in your presentation project(s) (which is just a physical artifact) unless you go down the route suggested by Jethro to generate your domain model into a separate project.
For the three tier architecture. I would consider doing Abstraction using Domain Model and Data model pattern rather then doing direct EF from Presentation Layer.
So the idea is that you have your Data Model which has EF POCO classes with Repositories which knows how to access these Classes for various CRUDs.
Your Domain Model would have models related to your Client (so you can put various ViewModels or Validation related code), It can be a WPF or MVC web app.
Now between these two there is a business which talks to both Domain and Data models.
Your Presentation Layer does know nothing about the EF/Data Layer/Repository. When you want to introduce new Data Framework or database, you just need to write new repository classes and data models classes (which prob. be with some sort of code gen).
This also allows your code to be Unit testable as well.
Scenario
Data Access Layer
EF's generated .edmx and classes
Used only to access the SQL Database and pass the data forward to the business layer
Business Layer
Business entities : contain all validation logic, marked with the [DataContract] attribute so that they can be passed as parameters to my web service
Problem
I want to use the repository pattern with this approach. The repository would contain all CRUD operations to be performed on the database, accepting and returning business layer entities. This means that the repository will reside in the business layer, because only the business layer can reference the data layer, not the other way round. I'm also planning to use the data layer assembly in other projects, that's why I would like to have the repository in the data layer, not the business layer (which is particular for this project).
What do you recommend? Should I keep the repository in the business layer and write one for each different business layer? Or should I keep the repository inside the data layer, not accepting or returning business entities.
Or, as an alternative, can anyone recommend a different approach, that would yield a more logical, scalable architecture?
Thanks for reading, waiting for answers
A repository is an abstraction over the data layer - to afford persistence ignorance to your application. It should only deal with data access and nothing more. It should not have any business logic.
The repository can and should accept and return DTOs (Data Transfer Objects) - these are simple objects that do not have behavior of their own and are used to transfer data between layers.
I would put it between the DAL and the BLL and only use it for data access from the BLL.
I like the accepted answer. Ideally, having a completely layer dedicated to the Repositories sounds right.
But I think, in a traditional 3-tier only application (e.g. "Data->Business->UI"), I would stick the Repositories in the Data layer. The reason I would put them in the Data Layer, is because they deal strictly with data access. The reason I would NOT put them in the Business Layer, is because they should NOT have any business logic to them.
I think repository interface should be in business layer, but implementation of this interface should be in data layer. Interface enable unit testing, but repository implementation is not responsibility of business layer.
I have an application with three layers (Presentation, Business Logic, and Data Access). In the data access layer, I have an object called Unit, and I have another object called Unit in the business layer.
When Insert() is called on the Unit object in the business layer, it calls the Insert() method on the corresponding object in the data access layer, and passes itself as the parameter. The problem I have is that the data access layer does not reference the business layer, and allowing it to do so would cause circular dependencies.
Is my approach flawed? If so, what would be a good solution to my problem?
You're right when you state that the way you're doing it would require a bidirectional dependency between layers, and that's almost always a bad thing. The reason for this dependency is that your business logic layer takes on some of the responsibility of the persistence layer (by implementing Insert() in the business logic layer).
It seems like you're mixing two incompatible concepts here.
First, you state that you have three layers in your code: presentation, business, and data access. The problem with this statement is that you also claim to be using an active record like pattern (unit.Insert()). If you truly have a distinct domain (business) layer and persistence (data access) layer, then the domain objects would not know how to Insert().
Take a look at the repository pattern. This pattern is better suited for establishing a distinct persistence layer. If you use this pattern, you can define an "Entity" in the persistence layer, and map your Unit object in the domain layer to the Unit object in the persistence layer. AutoMapper should save you from the pain of manually mapping the domain model to the entity.