Please help on choosing the right way to use the entities in n-tier web application.
At the present moment I have the following assembleis in it:
The Model (Custom entities) describes the fields of the classes that the application use.
The Validation is validating the data integrity from UI using the reflection attributes method (checks data in all layers).
The BusinessLogicLayer is a business facade for additional logic and caching that use abstract data providers from DataAccessLayer.
The DataAccessLayer overrides the abstarct data providers using LinqtoSql data context and Linq queries. And here is the point that makes me feel i go wrong...
My DataLayer right before it sends data to the business layer, maps (converts) the data retrieved from DB to the Model classes (Custom entities) using the mappers. It looks like this:
internal static model.City ToModel(this City city)
{
if (city == null)
{
return null;
}
return new model.City
{
Id = city.CountryId,
CountryId = city.CountryId,
AddedDate = city.AddedDate,
AddedBy = city.AddedBy,
Title = city.Title
};
}
So the mapper maps data object to the describing model. Is that right and common way to work with entities or do I have to use the data object as entities (to gain a time)? Am I clear enough?
You could use your data entities in your project if they are POCOs. Otherwise I would create separate models as you have done. But do keep them in a separate assembly (not in the DataAccess project)
But I would not expose them through a webservice.
Other suggestions
imho people overuse layers. Most applications do not need a lot of layers. My current client had a architecture like yours for all their applications. The problem was that only the data access layer and the presentation layer had logic in them, all other layers just took data from the lower layer, transformed it, and sent it to the layer above.
The first thing I did was to tell them to scrap all layers and instead use something like this (requires a IoC container):
Core (Contains business rules and dataaccess through an orm)
Specification (Seperated interface pattern. Contains service interfaces and models)
User interface (might be a webservice, winforms, webapp)
That works for most application. If you find that Core grows and becomes too large too handle you can split it up without affecting any of the user interfaces.
You are already using an ORM and have you thought about using a validation block (FluentValidation or DataAnnotations) for validation? Makes it easy to validate your models in all layers.
It may be a common practice to send out DTOs from serivce boundary (WCF service, etc.) but if you are directly using your "entities" in your presentation model, I don't see any benefit in doing that.
As to the code snippet you have provided, why not use AutoMappter? It helps by eliminating writing of boiler-plate mapping codes and does that for you if you have a set of convention in place.
Get rid of the model now, before removing it later will require refactoring the whole application. The last project i worked on used this architecture and maintaining the DTO layer and mappings to the database model layer is a huge pain in the arse and offers no usefull benefits. One of the main things that is anoying is that LinkToSql does not effectively support a disconnected data model. You cannot update a database table by creating a new DB entity with a primary key matching an existing record and then stick it into the data context. You have to first retrieve the entity from the database, update it then commit the changes. Managing this results in really nasty update methods to map all the properties from your DTOs to your LinqtoSql classes. It also breaks the whole deferred execution model of LinqToSql. Don't even get me started on the problems it causes with properties on parent classes that are collections of child DTOs (e.g. a customer DTO with an Orders property that contains a collection of order DTOs), managing those mappings is really really fiddly, i had to do some extensive optimisations because retrieving a few hundred records ended up causing LinqToSql to make 200,000 database calls (admittedly there was also some pretty dumbass code as well but you get the picture).
The only valid reason to use DTOs is if you want to have multiple pluggable Data Access Layers e.g. LinqToSql and NHibernate for supporting different DB servers. That way you can swap out the data access later without having to change any other layers. If you don't need to do this then save yourself a world of pain and just use the LinqToSql entities.
Related
I've built a web application with Entity Framework using POCO.
I'm using these POCO classes as my business objects and not just for persisting data which works fine until...
Now I need to add some logic into these classes to do thing like total up sales, order lines, etc.
Should I add methods to my POCO classes to enable this functionality or leave them purely for persisting data and create some kind of 'processor' whereby I pass in the business objects and get the values I require out.
Is there a best practice for this?
What is the architectural design you are using or want to use?
For example, if these are your domain entities, you should put as much as possible logic in them. If they are merely data containers and you don't have a real architecture in place, your logic would probably in some business component.
So if you provide your question with some more details, we can help you better.
I've been reading articles on StackOverflow and other sites all day about best architecture practices and there are just so many conflicting ideas and opinions.
I've finally settled on an approach, but I am having a really hard time deciding where to place the EF objects (DbContext, Fluent APIs, Seeding data, etc). Here is what I currently have:
ASP.NET MVC Project: The actual web project. Contains the standard views, controllers and View Models (inside a Models folder).
Domain Model Project: Contains all POCO classes that define the database (domain) objects. Currently, does not mention or reference any EF objects.
Service Layer Project: Contains service objects for each type of domain object (e.g., IProductService, IOrderService, etc). Each service references EF objects like DbSets and handles business rules - e.g., add a Product, fetch a Product, append a Product to an Order, etc.
So the question is, in this configuration, where do EF classes go? Initially I thought in the Service Layer, but that doesn't seem to make sense. I then thought to put them in the Domain Model Layer, but then it ties the Domain Models to EF, which is essentially a DAL / Repository. Finally, I thought about creating a separate DAL Project just for EF, but it seems like a huge waste considering it will likely have 3-4 files in it (DbContext and a few other small files).
Can anyone provide any guidance?
There is no need for Domain Model since it will be redundancy. EF classes directly can act as Domain Model and they are converted to View Models while sending it to View. EF can be separated into different class library. Most of them use repository pattern along with any ORM incase it would be easy if they go for replacement. But I've seen criticism over using repository pattern, check this out.
Here is what I do:
Data:
Has one class inheriting from DbContext.
It has all the db sets.
Overrides OnModelCreating.
Mapping primary keys and relationships.
Entities:
Has every POCO classes.
Each property is decorated with needed data annotations.
Services:
Each service has common methods (GetList(), Find(), Create(), etc.).
Business:
Called from clients, orchestrate using services to perform a specific task UserChangePassword (this will check if this can be performed, then perform the task, or return error/unauthorized statuses among many others to make the client shows the correct information regarding the task. This on my case is where I log.
Clients (Desktop/Web/Wpf/etc).
I'm not saying this is the best approach, I'm just sharing what's been working for me.
**Update 2**
I have a project with a typical 3 layer structure(UI/Domain/Data layer). What is the pros and cons to have both domain model entities in domain layer and data entities layer.
The possibility of changing to different database is slim. What is the pros and cons of having only data entities in data layer as domain model entities? What is the difference if ORM is used (Is it good practice to have both entities when ORM (NHibernate) is used)?
Please fire your ideas, or links, articles, books.
Update 3
In what circumstances we should use both domain entity and data entity?
Assuming your question is about DDD. In a typical DDD scenario, Domain entities are 'hydrated' by Data layer (which is often thin because it uses ORM). In order to hydrate Domain entities, Data layer has to have intimate knowledge of the domain. If you use ORM than you most likely not need separate 'data entities', ORM knows how to reconstitute your Domain objects. Hope this helps.
Using data entities with domain entities is a tricky thing to do and adds another not necessary layer of abstraction without adding any value.
You should either use full-featured domain model mapped via ORM or 'anaemic' data model (also mapped via ORM). Which one depends on your background, requirements and personal preferences.
In case of data model, you probably map directly tables to entities (one-to-one) without any complex stuff like inheritance hierarchy mapping. That's fine. The tricky thing is mapping 1:n relationships. With data model they tend to work well if you don't represent the 'many' side in object model. Why? Because both relation ends will easily be out of sync if you don't add custom code to handle these cases.
In case of domain model, you probably use repositories to fetch your aggregate roots.
There is exception to what I've written. It is legitimate to use both data entities and domain entities in CQRS architecture.
You use data entities if your data schema does not map exactly onto your domain entities. For example, consider a telephone number. In your domain entity, it may be one single property whereas in the database it may consist of an area code field and a telephone number field.
Contrary to what some answers suggest, the data access layer DOES NOT hydrate your domain entities and DOES NOT have intimate knowledge of them. Instead, your domain layer asks your data access layer for data needed to reconstruct instances.
The domain model should exist in as many places as possible to maximize code reuse and understanding. The exception to this would when using the domain model is prohibitively expensive, in either time, memory or transportation costs.
Let's say the you have have a supplier for parts. This supplier supplies thousands of parts to you, so the one-to-many in this case might be huge, especially considering the web of classes each part might bring along. However, you need a list of parts from a specific supplier for a specific widget. In this case, you create a value object with the just the data you need.
This value object can be a copy of the supplier object, with only the parts you need, or it can be a completely new class representing only the data you need.
The typical use case for this might be displaying the data on a web page, and your transferring the data via json.
I started my website, like stackoverflow, with a little technical debt that I'm trying to pay off. Being a contract developer, I've been in many places and see many different methods of achieving this result, but the way I'm going is..
Presentation (web)
Business Layer (old fashioned entity classes and BL layer)
Data Layer (DA classes to SQL Server via Stored Proc)
My question primarily concerns the Business Layer. Right now I have an Entity namespace and a BusinessLogic namespace.
The BL has a reference to the DA and the Entity.
The Entity has a reference to the DA
(The DA is "unaware" of the BL or Entity)
I really want all my churning of turning Data into Entities to occur within the BL -- thus the Business Logic. However, I want the Entity to be able to access the BL if need be -- and thus remove the Entity's reference to the DL.
So...
Is is "wrong" to have the BL and Entity objects within the same namespace so they can work together?
Essentially, I'm trying have an entity object like Employee (classic example, eh?) and have the Employee have a
public Hashtable[] SubordinateEmployees
property that returns a Hashtable of other Employee objects that report to this employee. But I don't want to load it until it's needed. So for most employees the property would never get accessed, but when it does, it self-loads with a call to the BL, which calls the DA.
Does the question make sense?
If so, does my solution?
Thanks so much in advance!
The usual way to deal with the kind of situation your example represents is with facades. Instead of trying to get the subordinate employees from the Employee object, you use a call to the business logic to get it.
hashtable = BL.GetSubordinateEmployees(supervisor);
That way you have a single point of access to the subordinates, and there is only one thing (the BL) accessing the data layer and creating Entities.
Let me see if I can show you a better way to think about this
you have your data access (sql server, mysql, flat xml files, etc.) all of this should be abstracted away nothing else in your application should care or know how you are getting your data, only that it dose, if anything else knows how you are getting your data you have a layer violation. if the DAL dose anything other then get data you have a layer violation. Next you implement a data access interface something like IDAL that your business layer uses, this is very important for making your code testable by forcing you to separate your layers.
Your data entities can be placed in the DAL name space or give them there own, Giving them there own forces separation. Data entities are dumb objects and should contain very little to no logic and are only aware of themselves and the data they have, THEY DO NOT CONTAIN BUSINESS LOGIC!, DATA ACCESS LOCIC, OR UI LOGIC. if they do you have a layer violation. The only function of a data entity is to hold data and be passed from one layer to the next.
Biz layer implements a data access interface like the IDAL we talked about before you can instantiate this with a factory, an IOC container, or all else failing a concrete type, but add a setter property so this can be changed for testing. The Biz Layer Only handles Business logic, it doesn't know or care where the data came from or where it's going, it only cares about manipulating the data to comply with business rules, this would include date validation, filtering (part of this is telling the DAL what data it needs, let the DAL figure out how to get it). Basically the BIZ handles all logic that isn't UI related or Data retrieval related. Just like the DAL the Biz should implement an Interface for the same reason.
The UI layer Accesses the Biz layer the same way the Biz layer accesses the DAL for the same reason. All the UI layer cares about is displaying data and getting data from the user. The IU Layer should not know anything about the business rules, with the possible exception of data validation required to populate the Data Entities.
The advantage of this architecture is it forces separation of concern making it easier to test, more flexible, and easier to maintain. Today you are building a web site but tomorrow you want to allow others to integrate vi a web service, all you have to do is create a web service that implements the IBIZ interface and your done, when you have to fix a bug in the BIZ layer, it's already fixed in both your website and web service.
Taking this to the next level, lets say you are doing a lot of heavy number crunching and you need more powerful servers to handle this so all you have to do is implement an IDal and IBIZ interface that are really wrappers to WCF that handles the communication between your servers, now your application is distributed between multiple server and you didn't have to change your code to do it.
So i am reorganizing a winforms C# solution to help decouple and make it cleaner and more organized. The solution tracks a small business orders,etc . .
I have broken out the projects so far into
App.View - all GUI Related Code
App.Data - just data structures and interfaces. No other implementation code
App.BusinessLogic - all business logic code that has no GUI references
I have some classes that i can't figure out where they belong. Please let me know your thoughts which project each class should go or if there is another project that should get created for this.
A Class that retrieves user preferences from a database
A Class that retrieves static data from our static data server and returns sets of data results.
A Class that brings down user entitlements
A model class that stores a hashtable of orders
A class that emails out messages on a user action
Actually, I think you have things a little off from a traditional layered architecture. Normally, the models of your data that your application works on would be kept in a business layer, along with the code to operate on them. Your data layer would have both the data models of your persistence framework and the code to interact with that framework. I think this might be the source of the confusion between the suggested locations of your classes and your reaction to it based on your comments.
From that perspective anything that retrieves or brings would necessarily be located in your data layer -- it's accessing data in persistent storage. What it retrieves are eventually converted into business layer objects that your business logic operates on. Things are are conceptual models -- like a table of orders -- or business actions belong in the business layer. I would agree with #Adron with, perhaps, the same confusion about where (3) goes depending on what it actually is.
More specifically:
User Preferences are business
objects, the thing that retrieves
them is a data layer object.
The static data maps on to a business
object (table or view or something),
the thing that accesses the external
server is a data layer object.
The user entitlement is a business object, the thing that retrieves it is data layer object.
A table of Orders is a business object
Emailing is a business activity, so the thing that mails people is a business object
[EDIT] My generalized 3-Tier Architecture for (simple) web apps
DataAccessLayer
This would include my TableAdapters and strongly typed DataTables and Factories that turn rows of my DataTables into business objects in pre-LINQ projects. Using LINQ this would include my DataContext and designer generated LINQ entities.
BusinessLayer
This would include any business logic, including validation and security. In pre-LINQ these would be my business objects and any other classes that implement the logic of the application. Using LINQ these are the partial class implementations of my LINQ entities to implement security and validation along with any other classes to implement business logic.
Presentation
These are my web forms -- basically the UI of the app. I do include some of the validation logic in the forms as an optimization, although these are also validated in the BL. This would also include any user controls.
Note: This is the logical structure. The project structure generally mirrors this, but there are some cases, like connections to web services, that may be directly included in the web project even though logically the components are really in the BL/DAL.
Note: I'll probably be moving to MVC over 3-Tier once ASP.NET MVC is in production. I've done some personal projects in Ruby/Rails and I really like the MVC paradigm for web apps.
You have specified that App.Data should contain only data structures and interfaces, no implementation code, which is fine if you want to do that, but that leaves you with nowhere to put your database access code except in your App.BusinessLogic assembly.
Perhaps you really need to rename App.Data to App.Model (or something similar), and have a new App.DataAccess assembly that talks to the database (perhaps implementing a Repository pattern). Having done that, I would split things up like this:
App.DataAccess
App.DataAccess
App.DataAccess
App.Model
App.BusinessLogic
I would probably go with
Data
Data
Data, although I'm not entirely sure what the class is doing
Data
BusinessLogic
-> App.Data
-> App.Data
-> App.BusinessLogic or App.Data - not sure exactly what this means.
-> App.BusinessLogic
-> App.BusinessLogic