When creating a Business Model in which layer (GUI, BLL, DAL) entities class must be defined?
Your entities are a part of your Business Logic. In your entities you define your business rules.
They should be ignorant of the type of Data Access you use. This can be done by using the Repository pattern. In your BLL you define your Repository interfaces which act on your entities. In a separate infrastructure project, you will define an implementation for the Repositories.
If you pass your entities to your GUI is a matter of choice. Sometimes it can be beneficial to use special crafted classes for passing data to your view but in a small project you could opt for passing your entities directly to your GUI.
You can define it in two places
Either create a new Layer Model/Entities (preferred)
or
Define them in Data Access Layer
I would say: in their own layer. The GUI, the business layer and the data access layer all use the entities. But the GUI doesn't depend on the data access layer, and the data access layer doesn't depend on the service layer. So entities must be in their own domain layer.
It depends from the way you want to use your entity. If it's simple POCO object, that used as DTO from db to you application, so i think that best place will be DAL. If you want to use your entity like part of business logic and it has some functional - so BLL will be the best place. But I don't think that there are some cases when it should be used and defined in GUI
I think that it's a good practice to have an ViewModel for any GUI purposes. Because when you use EF than it means that you interact with SQL somehow (in most cases). So you data is normalized. For there other hand many times you need denormalized data for GUI. That why i prefer to use ViewModel for GUI.
Related
I am trying to learn the idea of Domain Driven Design and trying to figure out where should we put the Database persistence code.
Going through the book "Implementing Domain Driven Design by Vaughn Vernon", I understand that the Repository or the Database operations (along with connections etc.,) have to be kept in the Model project (Domain Model Context) itself. Is my understanding correct?
I am referring to his sample of IdentityAccessContext, AgilePMContext etc., where there are interfaces to the repository. I had always grown with an idea of having a separate Data Layer and adding one here leads me to circular dependency. Because the Interfaces, Entities are declared in Model which is required for the Data layer and the Data layer needs to be referred from model for persistence.
Is this correct or am I missing something?
Going through the book "Implementing Domain Driven Design by Vaughn
Vernon", I understand that the Repository or the Database operations
(along with connections etc.,) have to be kept in the Model project
(Domain Model Context) itself. Is my understanding correct?
Repository abstractions (interfaces) should be in the Domain layer, but their concrete implementations are in an Infrastructure layer.
See his code samples for the book : https://github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_agilepm/src/main/java/com/saasovation/agilepm, for instance TeamRepository interface in domain/model and LevelDBTeamMemberRepository in port/adapter/persistence.
There's no circular reference because persistence is strongly coupled to Domain but Domain is only loosely coupled to persistence if it ever needs it (thanks to Inversion of Control, most of the time achieved by Dependency Injection).
I wouldn't say there's a data access layer per se.
Actually, repositories translate domain into data and viceversa using a data mapper.
Models, services or transaction scripts must use repositories to both get and persist objects. There's no circular reference here:
Service layer injects repository/repositories to implement domain operations. That is, a service will know what to do if it requires objects and it's not focused on how they're translated into data.
Repositories use a data mapper to persist and get data (1).
Data mapper usually is an OR/M like Entity Framework, NHibernate, Dapper...
Furthermore, a good DDD will enforce inversion of control and this will mean that:
Upper layers know about lower layers.
Lower layers don't own any reference to upper layers.
In summary, DDD doesn't have a DAL like you think, but it tries to abstract and encapsulate each concern in order to let upper layers be decoupled from the underlying data approach.
About the circular reference thing...
OP said:
Because the Interfaces, Entities are declared in Model which is
required for the Data layer and the Data layer needs to be referred
from model for persistence.
Double check your statement. If models represent higher layer of abstraction than data, why data should reference models?
It would be the model who requires the data. And the data should be accessed using interfaces to let the models be agnostic about the data access strategy. This is called inversion of control, as I said previously on this answer.
Maybe you think that data layer requires a reference to entities, because you're still thinking the old way, but if you practice a good separation of concerns and you work with a data mapper (or you implement it yourself), the data mapper just maps objects to raw data and viceversa, and it doesn't require a reference to concrete classes like domain objects (you should ask yourself how Entity Framework can persist your entities to your favourite database engine without even knowing about these entities (2)).
Anyway, as I said before on this answer too, you shouldn't think about a DAL but a bunch of repositories and a data mapper, or just repositories (see exception (1)).
Usually dependent lower layers are instantiated and given to upper layers using dependency injection pattern (a possible implementation of inversion of control).
(1) Exception to this rule: if we're no talking about a relational storage, maybe there's no data mapper at all, and repository implements its interface by accessing the data with lower level of abstraction/encapsulation. For example, if the repository implements its operations to store data in XML, then it would use an XDocument or XmlDocument internally and there's no actual data mapper at all.
(2) Actually OR/M frameworks like Entity Framework can know how's your model by configuration. While it doesn't require a reference to your concrete domain to compile, it requires you to provide class maps using Code First or other approaches)
In a layered application, is it good practice to have you entities defined in a shared layer? I figure that I will be using them across all layers. Or do they belong in the business layer?
MSDN's layered application guideline puts the business entities in the business layer
The Layered Architecture Sample for .NET puts the entities in the shared layer
Can it be like this?
Presentation
Business
Data
Shared
Entities
Or must it be like this
Presentation
Business
Entities
Data
Shared
What to do and why?
I usually organize projects in following structure:
Presentation (MVC application)
try to keep your controllers small as possible. Do not put any business logic into controllers. Relay on service interfaces instead concrete implementations. Use dependency injection.
Business layer
service classes belong here and they should contain all business logic
i group related services into folders by feature. Each service queries the DB with entity framework and maps the results into Model (a.k.a. View Models, Presentation Objects) objects. So the service layer does not return DB entities but return POCO classes.
shared folder contains services which are shared across multiple services (they are more like infrastructure code but i prefer to keep them inside the business/service project)
DAL data access layer
I prefer to use only entity framework without any other abstraction upon it. Some people use Repositories or implementing own unit of work pattern, but i do not recommend to do this. Entity framework is already implementing unit of work and encapsulating database selects with linq so there is no need for more abstraction.
this layer contains only Code First classes (entity framework entities)
I would say it depends if these entities contain business logic or not.
From the Layered Application Guidelines :
Business entities also validate the data contained within the entity
and encapsulate business logic to ensure consistency and to implement
business rules and behavior.
In contrast, the Layered Architecture Solution Guidance seems to rely on code generation to create Entities, they are mere data containers with little to no logic in them.
Rich domain entities tend to not be in a Shared module, since it would mean carrying around a ton of behavior that you don't want everyone to have (imagine being able to manipulate business logic directly on the client side...) Anemic ones on the contrary are lightweight and may be happily and conveniently distributed everywhere.
My approach is a little bit different. In data layer I store all my entities and in shared layer I have DTO object (Domain Transfer Objects) which are exact copy of entities but without Entity Framework control. To map each other, I'm using mapper (AutoMapper) which is fluent and easy to use.
I can't understand why Entity Framework doesn't support interfaces, using only instances.
Domain layers are communicating the other layers via Data Transfer Objects(DTOs). I confused about DTOs.
DTO 1 is between Domain and Presentation Layer.
DTO 2 is between Domain and Data Layer.
Should I create two different DTO objects between layers or only one DTO. Which is the proffesional way?
Lets go through all your layers:
Data Access Layer (DAL). It is used in order to get data from database (DB).
Usually it knows about Domain Entities and Domain Layer.
The DAL can return either Domain Entities or DTOs (DB oriented data structures). These DTOs or Domain Entities can be used in order to build DTOs of Presentation Layer (view models) if it is needed.
Domain Entities usually are heavy and require data mappers or any ORM. I prefer working with Domain Entities, map them and avoid other DTOs. Otherwise DTOs should be mapped also.
Domain Layer (Domain model). It is used in order to represent Business entities and their behaviour, business rules, pure business logic.
Domain Layer should know nothing about the way the entities are stored somewhere (e.g. in DB). It can have its own DTOs which can be results of refactoring Introduce Parameter Object.
Presentation Layer (UI). It is used in order to present UI to users.
It should know about Data Access Layer to load data from DB and about Domain Layer to have access to its business logic.
It can have its own DTOs - view models, which are user interface friendly representation of Domain Entities or DB friendly DTOs. It is responsibility of Presentation Layer to know about view models.
If you are going to have only one presentation your Application Infrastructure can be implemented as part of presentation layer also, but usually it is a separate Application Layer.
It really depends on your your specific needs.
In a general sense, you should create 2 sets of DTO's. This allows for better de-coupling of different layers and makes the architecture of your system more flexible. The specific reasons or cases where it is needed are for example:
Sharing DTO's may not be possible, e.g. because there are differences in technologies used, e.g. a web service and data layer are written in C# and the presentation layer is written in Java.
DTO's are not necessarily the same, i.e. your DTO for the interaction with the database layer may be modelled on the database structure but you may expose it differently to the presentation layer.
Having said that, if you can live with the limitations of having one set of DTO's, you can share them if it suits your needs as it produces less code to write and maintain.
Your image shows two DTO object named DTO1 and DTO2.
DTO1 is sharing data between presentation layer and domian layer. You can call them as ViewModel classes.
DTO2 is sharing data between domain and data layer. You can call them as Data Transfer Objects (DTOs).
So You can use two different transfer objects.
If we assume that you use two separated DTOs (DTO1 and DTO2),
answer is simple:
You must create two separate DTO in this case: DTO1 and DTO2.
Even if they are identical, they should be implemented as separated classes.
It is because DTO1 is created in Domain Layer but DTO2 is created in Data Layer (according to yor picture).
Note that in some solutions, two DTOs are not used - sometimes, there is only one DTO.
Say i have 3 layers
layer 1: WPF Project (contains: xaml, viewmodels, mvvm framework)
layer 2: business logic layer (contains: plain c# classes)
layer 3: entity framework (contains: repository/data access classes)
when you dont want to expose your DAL(layer 3) to View(layer 1)
how do you implement the business logic layer well?
im having a hard time putting values back and forth the BLL objects and DAL entities.
can you please help?
Entity Framework doesn't work really well in a "disconnected" model. Unless something has changed, I've never been able to get it to work great easily.
You could use AutoMapper in Layer 2 to create ViewModels to present to Layer 1, but then you'd still have to send the changes back to Layer 3, which could be a pain.
If you're only developing a small app that will not change in the foreseeable, then just do whatever is quickest now. If you want a long-term maintainable app, then let me put forth the following.
The problem with this vertical layer approach is that whenever you need something in the view, you will have to add it to both the Business Layer (even if the business layer doesn't care about it), and the Data Layer. This requires your business layer to look like 1) UI views of the data 2) business views of the data and 3) the database representation of the data. That and/or you need a lot of mapping in-between layers. All of which dilutes business layer's actual purpose of representing business logic. What tends to happen then is that all the business logic gets migrated into transaction methods (that could just as well be static methods) to just change states on data objects. There's nothing at all wrong with that if your problem domain is nothing but CRUD with no complex logic. With complex logic, such business methods can get pretty tricky or even have undefined outcomes (because complex interdependencies on "fields" can be contradictory and hard to resolve).
Assuming you have complex logic, user views of data and business representations of data are often very different, and so UI views end up with specialized models of the data. If I were you, I just embrace this and use a simple version of the CQRS principle. That is, have the data for your UI views come from a different place than where your business operations are executed. In your case, I might have an EF Model in your DAL that only services your UI views, and gives them exactly what they need (whether by database views, stored procedures, or pre-compiled report tables). Then create a separate EF model that services only the needs for your Business entities. Then when you are ready to perform an actual business action, the UI's viewmodel action method can load the business object from the business EF model (or better yet, call an object factory from the business layer which does this) and run an appropriate action on the business object. Note that I'm also making the assumption here that your database is highly relational (mostly 2nd and 3rd normal form) and you are set on using EF.
I would not try to make your View Models into business logic. This makes your business logic not easily reusable on other platforms or applications (like web). MVVM should only service the UI. In my mind, the V (view) represents what the user sees and operates. The M (model) represents what the user chose on that view. And the VM (view model) translates between the two. Your program should then take the user's validated choices (UI model) and extract the needed data out of it to perform an appropriate business operation.
Instead of exposing all of your DAL to View Layer, just exchange your domain objects (EF objects) between all layers. The structure may be similar to the following:
Presentation Layer-------- ^
BLL --------------------------- | Data objects
DAL (Repositories etc.)--- |
So, all of your layers will be disconnected; but they will share the same domain objects. In real world, you can implement a similar structure by creating a seperate dll for Entity Framework entities which is shared by all layers. Note that ObjectContext shall be only visible to DAL (by default, entities and object context are generated in the same dll, you need to seperate this into two dlls).
In addition to the answer by Daryal, you can define your business-objects in your BL to be POCO's, and use EF in your DAL layer to read them from or persist them to the database.
If you define an repository-like interface in your BL (or unit-of-work, whatever naming you give it), and implement the interface in your DAL, then all you need is a little DI to get an instance of the repository-class without having to reference the DAL all the time. It works like a charm for me.
See here and here for more information.
Your ViewModels are your application in MVVM, so they should be handling things like data access through your Repository classes, or business logic (either directly, or indirectly using your validation classes).
If you don't want to directly reference the classes, use an Interface but be aware that you'll need to have some way of passing your inherited class to your ViewModel. I once did a project where we had a library of shared interfaces, such IRepository interfaces, and everything was imported/exported using MEF so the layers didn't reference each other directly.
The final (simplified) layout was:
Models -> Contained plain data objects that could do simple validation on their own data (length, min/max values, etc) but that didn't do any advanced validation or business logic. Did not reference any other library.
Common -> Contained interfaces, utilities, and other commonly shared classes. Referenced the Model library only.
DAL -> Contained Data Access and Repositories based on repository interfaces found in Common library. Referenced Common library for interface definitions and utilities, and Model library because it contained the data models used or returned in data access calls
ViewModels -> Contained application and business logic. Referenced Common for its utilities and interfaces, and Models for the data models
Client -> Contained Views. Referenced Models and ViewModels so it could write DataTemplates for both object types
Entity framework is suppouse to be used as "Logic Layer" by itself.
Your idea may have some sense, to use combine technologies.
Howevere, I think some of those Micros. libraries, where designed to be used separately, unless, otherwise explicitly combined & mentioned in their websites.
Good Luck.
I second daryal and I have implemented this in some projects. It is absolutely OK to use POCO as business objects.
Another approach instead of creating 2 projects (one for DB Context and one for Entities) is to use one DAL/DATA project only and reference it in BLL. Then inherit the POCO class in BLL and use that class in UI layer. Below is the basic sample code:
// assume this is EF generated POCO
namespace Owner.Project.Data{
public partial class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
}
}
// this is manually created class in BLL
using Owner.Project.Data;
namespace Owner.Product.Business{
public class StoreProduct : Product {
public bool Add (string productName){
// TODO - add product using EF as you normally do
}
}
}
Now you can reference the BLL in your UI project and use StoreProduct class there. To achieve loosely coupled pattern, Of course you could also inherit the StoreProduct class from an IStoreProduct interface and make use of it in UI or web service but that is another topic.
I have an ASP.NET app with a three layer architecture:
Presentation layer: ASP.NET
Bussiness Layer: C# library.
Data Access Layer: C# library with
ADO.Net Entity Framework objects.
Some methods on Bussiness layer would return ADO.NET entity objects but, data access layer is not visible at Presentation layer I can't do that.
My question is: On a design view, Is it correct to expose Entity Objects in the Presentation Layer? I think I only have to link Data Layer library with ASP.NET app.
Thank you!
It's absolutely desirable to have your entity objects available for use and consumption in your presentation tier. That's what all the work is for.
Binding collection of objects to a grid/listview/dropdown
Splashing a single object (i.e. customer) onto a form for read/update/delete
This makes your life easier by far. Otherwise you'd have to pass string after int after double after string between your presentation and business layers.
These may be Entity objects or even your own POCO objects that were hydrated from the Entity objects.
I would even go so far as to say that your Entites should be in their own assembly separate from the DAL.
I suggest that you look into the concepts of View objects...or Data Transfer Objects (DTO). You might consider using a tool like AutoMapper or similar which will create a view specific domain object out of your entities. In general you may have screens that need an entity present to perform its work. But more often than not you will need to pass several different entities. In this case you are better off creating one DTO that contains all of these entities. By doing this you are adding a layer of separation between your presentation layer and your business layer. Often times your entities have more power than you might want to expose to your presentation layer. And...vice versa. Frequently you may need to get some UI messages out to the presentation layer based on some validation flagged in your business layer. Rather than make your ui more complex than it needs to be (by passing in your full entities) you can only pass in what the UI needs in the form of the DTO. Also, there is never a need for your business objects to care about anything specific to the presentation layer. I suggest that you not databind directly to anything as far back as the data access layer. Technically your presentation layer should know as little as possible about your business layer. In the case of MVP or MVC this is very easy to achieve by disconnecting the front end and the back end by way of this additional separation!
I think no, it is not, the best way to do that is to separate data classes from behavior, and reference only data classes in presentation level.The good approach I think to use WCF see this link
See Supervising Controller and Passive View
If you pass the Entity, you are essentially Supervising controller. Otherwise you are Passive View.
Supervising controller is less work, but less testable. Supervising Controller also says databinding is OK.
Passive view is testable but a LOT more work. No databinding. Lots of properties.
Typically I stick with Supervising Controller. You typically don't need that level of testability and it isn't worth the extra trouble.