Onion Architecture - Where to put complex database query lookup - asp.net-mvc

I've been struggling with a design decision and was hoping for some feedback.
Architecture summary:
ASP.NET MVC WebAPI solution with a SPA frontend written in KnockoutJS and Entity Framework hooked up to a SQL DB.
The problem: we have two entities that pull a value (Rate) from a somewhat complex lookup table. The lookup table filters down to a distinct option based on 5 parameters, all 5 parameter values can be determined based on properties on each entity or a related table. On top of this look up value, both entities can have "Rate Modifiers" which can add another small amount to this lookup value.
The question: where should we put this lookup logic if we would like this calculated rate to be available anytime we use these two entities?
Service layer: have a service to request these entities, request
the entities from the Data (Infrastructure) layer repository, then
make individual calls back to the data layer to get the computed
rate
Data layer: inside the data layer repository get all the
entities and lookup the values there within the repository
UI layer: just send the entities to the UI layer and then have web
services to retrieve the rates for the 5 parameters
DB: Create a view in the db for these entities that does all the
rate lookup logic for us in the db
Other suggestions?
I see advantages and disadvantages to all of these options and none of them feel quite right to me. Option 3 feels like it's the cleanest, but is probably the least performant and is the most chatty. options 2/4 seem messy putting business-like logic in the data layer and option 1 feels a little over complex and inefficient.
Any insight would be greatly appreciated! Thank you.

If seperation of concerns or keeping everything clean is your concern, then it is best to keep it in the Service layer. Just as you suggested ,having the UI layer call the service layer which in turn calls the datalayer. The service layer is where the business logic usually lies. This is the ideal situation though.
However, if speed is your concern I think it is better to keep things in the DB layer probably as a stored procedure. In my experience this performs really well. But generally it is best not to spread business logic across layers.
Whatever solution you use , it is best to choose based on what your priority is - seperation of concerns or speed ,etc.
Do let us know what you went with.

Related

Where and how to convert data values subject to preferences/unit conversions

I'm working on a ASP.NET MVC project with the typical structure/architecture: (thin) controllers, service layer, repositories. We're using DTOs to hit the service layer and afterwards model/entities.
The application deals with weight and distance fields that can be displayed according to user's preferences (metric or imperial system). These values are always persisted using the metric system so these values are being converted (if necessary) when displayed and when entered by user. This is currently being done in the service layer, which handles the mapping between entities and DTOs and vice-versa and converters these fields as well (if preference is imperial system). For example, in a GET scenario this unit conversion is being handled (manually) as a post step after mapping to DTO and per entity.
As the application grows this is getting boring and not really optimal so wanted to get some ideas regarding the following:
The decision/idea is that from the service layer down, the system always deals with metric system because user preferences is kind of a GUI detail and shouldn't be factored in the model. So the unit conversion is being done at the service layer. Any comments if this is the best place to perform this? I wouldn't like to perform this in the Controllers because in the near future we plan to have as well a mobile app and the service layer should be common.
The unit conversion (helper methods) is currently being done manually, let's say, after mapping to DTO (if getting info) and per entity. I'd like to get some ideas on how could I make this step a bit more automated or better designed? Maybe mark the properties that can subject to conversion with an attribute and somehow pick that up and convert automatically but I can't seem to find a good idea for this. Any ideas?

Understanding why we use data transfer objects for data contracts in place of database entites

In situations where the client consuming a web service is looking for data that at present matches a database entity one to one (ie. GetAccount, GetTransactions); we still want to use a data transfer object (dto) to decouple the two to allow the database entity to change if needed, without the changes rippling through the entire system? If so, from a consuming standpoint, we don't want a client's model directly based on the data transfer object. We would want to cast whatever was being returned from the web service to a local model, for the same reasons we used a DTO in the first place? Do I have that right?
The DTO matches the shape of the data that you want to transfer. If that matches the underlying data model then so be it but that is by the by. You might at some point change the shape of the underlying data model but the DTOs would not change.
Also, a DTO is what would get passed by a web service to a client. If you have your data model defined on a server then you don't want a distributed client to have to know about that data model.
Finally, your entity classes might contain additional logic whereas a DTO is simply properties exposing data and nothing else.
Your application can have many conceptual layers. Data Layer, Business Layer, Service Layer, Presentation Layer to name a few. Each has a specific function with an input and output. The goal is how to design a system that is loosely coupled (i.e. things don't rely heavily on one another so any changes are isolated and have minimum impact). You want to maximise maintainability, improve re-use and maximise speed. The trick is to keep complexity down but build in some basic separation that allows you to move your design forward easily as you need it. Keep in mind YAGNI! YOU AINT GONNA NEED IT! People tend to look for and design the most complicated architectures for problems they will never encounter! The number of times I have heard "We have a separate data tier so we can swap out the database in the future"...yet I have never seen it happen! A simple Repository Pattern works.
As per previous poster, you have data in the database (in a physical model) that you want to get into your application transformed into a conceptual model. Any clients will then consume your conceptual model. I would do this immediately at or after your application code has retrieved the data from the database from your data layer. This ensures any changes made to your database are isolated from the rest of your application. Therefore you don't have to start changing your User Interface because you have changed the name of a database field. You just have to update your data layer.
If you choose Entity Framework as your data access strategy it will map your database to a conceptual model for you. If you are converting other data objects from one type to another look at technologies like AutoMapper. You can map your Entity Framework POCOs to a service contract (XSD). From the client perspective 'you could' write a client proxy that calls your web service, maps the returned service contract to a nice shared conceptual object model.
Keep it simple. Keep re-use and simplicity at the heart of what you choose. If you start seeing database column names in your client objects, you need to start thinking about putting in some abstractions in much earlier in your solution to insulate your app from changes.

Should services always return DTOs, or can they also return domain models?

I'm (re)designing large-scale application, we use multi-layer architecture based on DDD.
We have MVC with data layer (implementation of repositories), domain layer (definition of domain model and interfaces - repositories, services, unit of work), service layer (implementation of services). So far, we use domain models (mostly entities) across all layers, and we use DTOs only as view models (in controller, service returns domain model(s) and controller creates view model, which is passed to the view).
I'v read countless articles about using, not using, mapping and passing DTOs. I understand that there's no any definitive answer, but I'm not sure if it's ok or not returning domain models from services to controllers. If I return domain model, it's still never passed to the view, since controller always creates view-specific view model - in this case, it seem legit. On the other hand, it doesn't feel right when domain model leaves business layer (service layer). Sometimes service needs to return data object that wasn't defined in the domain and then we either have to add new object to the domain that isn't mapped, or create POCO object (this is ugly, since some services return domain models, some effectively return DTOs).
The question is - if we strictly use view models, is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer? If so, is it ok to adjust domain models based on what services need? (Frankly I don't think so, since services should consume what domain has.) If we should strictly stick to DTOs, should they be defined in service layer? (I think so.) Sometimes it's clear that we should use DTOs (e.g., when service performs lot of business logic and creates new objects), sometimes it's clear that we should use just domain models (e.g., when Membership service returns anemic User(s) - it seems it wouldn't make much sense to create DTO that is the same as domain model) - but I prefer consistency and good practices.
Article Domain vs DTO vs ViewModel - How and When to use them? (and also some other articles) is very similar to my problem, but it doesn't answer this question(s). Article Should I implement DTOs in repository pattern with EF? is also similar, but it doesn't deal with DDD.
Disclaimer: I don't intend to use any design pattern only because it exists and is fancy, on the other hand, I'd like to use good design patterns and practices also because it helps designing the application as a whole, helps with separation of concerns, even though using particular pattern isn't "necessary", at least at the moment.
it doesn't feel right when domain model leaves business layer (service layer)
Makes you feel like you are pulling the guts out right? According to Martin Fowler: the Service Layer defines the application's boundery, it encapsulates the domain. In other words it protects the domain.
Sometimes service needs to return data object that wasn't defined in the domain
Can you provide an example of this data object?
If we should strictly stick to DTOs, should they be defined in service layer?
Yes, because the response is part of your service layer. If it is defined "somewhere else" then the service layer needs to reference that "somewhere else", adding a new layer to your lasagna.
is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer?
A DTO is a response/request object, it makes sense if you use it for communication. If you use domain models in your presentation layer (MVC-Controllers/View, WebForms, ConsoleApp), then the presentation layer is tightly coupled to your domain, any changes in the domain requires you to change your controllers.
it seems it wouldn't make much sense to create DTO that is the same as domain model)
This is one of the disadvantage of DTO to new eyes. Right now, you are thinking duplication of code, but as your project expands then it would make much more sense, specially in a team environment where different teams are assigned to different layers.
DTO might add additional complexity to your application, but so are your layers. DTO is an expensive feature of your system, they don't come free.
Why use a DTO
This article provides both advantage and disadvantage of using a DTO, http://guntherpopp.blogspot.com/2010/09/to-dto-or-not-to-dto.html
Summary as follows:
When to Use
For large projects.
Project lifetime is 10 years and above.
Strategic, mission critical application.
Large teams (more than 5)
Developers are distributed geographically.
The domain and presentation are different.
Reduce overhead data exchanges (the original purpose of DTO)
When not to Use
Small to mid size project (5 members max)
Project lifetime is 2 years or so.
No separate team for GUI, backend, etc.
Arguments Against DTO
Duplication of code.
Cost of development time, debugging. (use DTO generation tools http://entitiestodtos.codeplex.com/)
You must synchronize both models all the time. (personally, I like this because it helps know the ripple effect of the change)
Cost of developement: Additional mapping is necessary. (use auto mappers like https://github.com/AutoMapper/AutoMapper)
Why are data transfer objects (DTOs) an anti-pattern?
Arguments With DTO
Without DTO, the presentation and the domain is tightly coupled. (This is ok for small projects.)
Interface/API stability
May provide optimization for the presentation layer by returning a DTO containing only those attributes that are absolutely required. Using linq-projection, you don't have to pull an entire entity.
To reduce development cost, use code-generating tools
I'm late to this party, but this is such a common, and important, question that I felt compelled to respond.
By "services" do you mean the "Application Layer" described by Evan's in the blue book? I'll assume you do, in which case the answer is that they should not return DTOs. I suggest reading chapter 4 in the blue book, titled "Isolating the Domain".
In that chapter, Evans says the following about the layers:
Partition a complex program into layers. Develop a design within each layer that is cohesive and that depends only on the layers below.
There is good reason for this. If you use the concept of partial order as a measure of software complexity then having a layer depend on a layer above it increases complexity, which decreases maintainability.
Applying this to your question, DTOs are really an adapter that is a concern of the User Interface / Presentation layer. Remember that remote/cross-process communication is exactly the purpose of a DTO (it's worth noting that in that post Fowler also argues against DTOs being part of a service layer, although he isn't necessarily talking DDD language).
If your application layer depends on those DTOs, it is depending on a layer above itself and your complexity increases. I can guarantee that this will increase the difficulty of maintaining your software.
For example, what if your system interfaces with several other systems or client types, each requiring their own DTO? How do you know which DTO a method of your application service should return? How would you even solve that problem if your language of choice doesn't allow overloading a method (service method, in this case) based on return type? And even if you figure out a way, why violate your Application Layer to support a Presentation layer concern?
In practical terms, this is a step down a road that will end in a spaghetti architecture. I've seen this kind of devolution and its results in my own experience.
Where I currently work, services in our Application Layer return domain objects. We don't consider this a problem since the Interface (i.e. UI/Presentation) layer is depending on the Domain layer, which is below it. Also, this dependency is minimized to a "reference only" type of dependency because:
a) the Interface Layer is only able to access these Domain objects as read-only return values obtained by calls to the Application layer
b) methods on services in the Application Layer accept as input only "raw" input (data values) or object parameters (to reduce parameter count where necessary) defined in that layer. Specifically, application services never accept Domain objects as input.
The Interface Layer uses mapping techniques defined within the Interface Layer itself to map from Domain objects to DTOs. Again, this keeps DTOs focused on being adapters that are controlled by the Interface Layer.
In my experience you should do what's practical. "The best design is the simplest design that works" - Einstein. With that is mind...
if we strictly use view models, is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer?
Absolutely it's ok! If you have Domain Entities, DTO's and View Models then including database tables you have all the fields in the application repeated in 4 places. I've worked on large projects where Domain Entities and View Models worked just fine. The only expception to this is if the application is distributed and the service layer resides on another server in which case DTOs are required to send across the wire for serialization reasons.
If so, is it ok to adjust domain models based on what services need? (Frankly I don't think so, since services should consume what domain has.)
Generally I'd agree and say no because the Domain model is typically a reflection of the business logic and doesn't usually get shaped by the consumer of that logic.
If we should strictly stick to DTOs, should they be defined in service layer? (I think so.)
If you decide to use them I'd agree and say yes the Service layer is the perfect place as it's returning the DTOs at the end of the day.
Good luck!
It seems that your application is big and complex enough as you have decided to go through DDD approach.
Don't return your poco entities or so called domain entities and value objects in you service layer. If you want to do this then delete your service layer because you don't need it anymore! View Model or Data transfer objects should live in Service layer because they should map to domain model members and vice versa.
So why do you need to have DTO? In complex application with lots of scenarios you should separate the concerns of domain and you presentation views, a domain model could be divided into several DTO and also several Domain models could be collapsed into a DTO. So it's better to create your DTO in layered architecture even it would be the same as your model.
Should we always use DTOs for communication with service layer?
Yes, you have to return DTO by your service layer as you have talk to your repository in service layer with domain model members and map them to DTO and return to the MVC controller and vice versa.
Is it ok to adjust domain models based on what services need?
A service just talks to repository and domain methods and domain services, you should solve the business in your domain based on your needs and it's not the service task to tell the domain what is needed.
If we should strictly stick to DTOs, should they be defined in service layer? Yes try to have DTO or ViewModel just in service later because they should be mapped to domain members in service layer and it's not a good idea to places DTO in controllers of your application(try to use Request Response pattern in your Service layer), cheers!
Late to the party, but I’m facing the exact same type of architecture and I’m leaning towards “only DTOs from service”. This is mainly because I’ve decided to only use domain objects/aggregates to maintain validity within the object, thus only when updating, creating or deleting. When we’re querying for data, we only use EF as a repository and maps the result to DTOs. This makes us free to optimize read queries and not adapt them to business objects, often using database functions as they are fast.
Each service method defines its own contract and is therefore easier to maintain over time. I hope.
So far, we use domain models (mostly entities) across all layers, and we use DTOs only as view models (in controller, service returns domain model(s) and controller creates view model, which is passed to the view).
Since Domain Model provides terminology (Ubiquitous Language) for whole your application it is better to use Domain Model widely.
The only reason to use ViewModels/DTOs is an implementation of MVC pattern in your application to separate View (any kind of presentation layer) and Model (Domain Model). In this case your presentation and domain model are loosely coupled.
Sometimes service needs to return data object that wasn't defined in the domain and then we either have to add new object to the domain that isn't mapped, or create POCO object (this is ugly, since some services return domain models, some effectively return DTOs).
I assume that you talk about Application/Business/Domain Logic services.
I suggest you return domain entities when you can. If it is needed to return additional information it is acceptable to return DTO that holds several domain entities.
Sometimes, people who use 3rd part frameworks, that generates proxies over domain entities, face difficulties exposing domain entities from their services but it is only a matter of wrong usage.
The question is - if we strictly use view models, is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer?
I would say it is enough to return domain entities in 99,9% cases.
In order to simplify creation of DTOs and mapping your domain entities into them you can use AutoMapper.
If you return part of your domain model, it becomes part of a contract. A contract is hard to change, as things outside of your context depend on it. As such, you would be making part of your domain model hard to change.
A very important aspect of a domain model is that it is easy to change. This makes us flexible to the domain's changing requirements.
I'd suggest analyzing these two questions:
Are your upper layers (i.e. view & view models / controllers) consuming the data in a different way of what the domain layer exposes? If there is a lot of mapping being done or even logic involved I'll suggest revisiting your design: it should probably be closer to how the data is actually used.
How likely is it that you deeply change your upper layers? (e.g. swapping ASP.NET for WPF). If this is highly unlike and your architecture is not very complex, you may be better off exposing as many domain entities as you can.
I'm afraid it is quite a broad topic and it really gets down to how complex your system is and its requirements.
In my experience, unless you are using an OO UI pattern (like naked objects), exposing the domain objects to the UI is a bad idea. This because as the application grows, the needs from the UI change and force your objects to accommodate those changes. You end up serving 2 masters: UI and DOMAIN which is a very painful experience. Believe me, you don't want to be there. The UI model has the function of communicating with the user, the DOMAIN model to hold the business rules and the persistence models deals with storing data effectively. They all address different needs of the application. I'm in the middle of writing a blog post about this, will add it when it's done.

Good implementation approach for Layered application with 3-tier architecture?

I am developing an application using MVC3 and Entity Framework. Its a three layered approach with Presentation Layer hosted in Web Server and Business Layer and Data Access Layer in Application Server. We are not exposing the Object Context to Presentation Layer or Business Layer. Object Context is wrapped in Data Access Layer only and exposing data access and data persistence as functionalities as Data Access Layer methods(ie data access logic is separated and implemented in Data Access Layer only). Business Layer is calling data access layer methods and returns data to Presentation Layer.
My concern is most of the Business Layer Methods are for just to access the data and it is just forwarding the call to Data Access Layer without any operation. So we are repeating the code in both layers. Do we have any other better approach to avoid this duplication.
Is it a good practise to implement the data access logic in the business layer in Layered approach?
Can someone suggest a good implementation approach for Layered application with 3-tier architecture?
If you find yourself that all that your business layer is doing is simply delegating the calls to the data access layer then this is a strong indication that this business layer is probably not necessary for your application as it brings no additional value. You can get rid of it and have the controllers talk directly to the data access layer (via an abstraction of course) - that's what most of the tutorials out there show with the EF data context.
In simple applications that are consisting mainly of CRUD actions, a business layer might not be necessary. As your application grows in complexity you might decide to introduce it later, but don't do too many abstractions from the beginning especially if those abstractions don't bring you any additional value.
As previously mentioned there is no "right" way to set things up. I have found a few things over the years that help me decide which approach to take.
Two-Tiered
If your shop is stored procedure heavy with a lot of database programmers and tends to put business logic in the database then go with a two-tiered approach. In this situation you will find that your business layer is generally just calling the data layer. Also, If your code base and pages tend to be small and you never repeat functionality then go with a two tiered approach. You will save a lot of time.
Three-Tiered
If your shop likes to have a lot of business logic in code and that logic is repeated everywhere then go with three-tiered. Even if you notice a lot of your business layer just calling the data layer you will find over time when you add functionality that it is a whole lot easier to just add code to the business layer. Also, If you have a large code base with a ton of pages with a lot of repeated logic then I would definitely go with this approach.
I have found a mixture of both in our enterprise level application at my work. The problematic areas are the ones where dynamic sql (gag) was used and business logic was repeated over and over. I'm finding as I refactor I pull this code into a 3-tiered architecture and save myself a ton of time in the future because I can just reuse it.
I don't think its necessarily bad to duplicate the code for logical separation. Time will come when this will pay off. Say you will replace SQL server by Oracle. Or Microsoft will come up with Linq 2.0 and some implementations will change. You will be thanking yourself for having it separate, while those who called database right from the business layer will have to do modifications in both places - DAL and BLL.
For what its worth. But again, there's no right answer, up to utility, usability, convenience, and most importantly having it matching its purpose.
Hope this is of help.

ASP.NET MVC Model & Business Objects

I am looking for some guidance on how to incorporate business rules into an asp.net mvc application and how they relate to the model.
First a little background so we know what kind of solutions are relative for this question. At work we use WinForms, MVP, BusinessObjects, DataAccessObjects, and DataTransferObjects. The boundaries of the layers use DTOs to send parameters to methods and as return types, or return List types.
Right now we are adding a facade layer to translate the DTOs into Domain Objects for the UI to work with, since the architect does not like how using DTOs in the PresentationLayer is working currently. I am comfortable about all of this in theory aside from it being practical or not.
I am making a website for fun, but for considerations lets say it serves the same amount of traffic as SO, something like 60,000 hits a month last I heard. I am comfortable with the mechanics of the controllers and the views, and how the model integrates with the two.
I am using NerdDinner as a sample for building the site and I follow the Repository pattern implementation in the examples. What I don't get is how to incorporate business objects into the mix.
I hear people talk about LINQ as the DataAccessLayer/DataAccessObjects. If I force all of my requests though the business objects as I am used to I have introduced some weird dependencies. Both my UI and my BO have to know about my DAO.
What would kind of make sense is to use the LINQ classes as a true DAO layer, hide it behind the BO, and have the BO transform between POCO and LINQ objects.
My only concern there is I am fine with binding my UI to LINQ classes, and don't really need all the extra work, I am happy with a thin lightweight approach as in NerdDinner.
So what I have essentially is the Repository that is instantiated in the controllers that takes and return LINQ objects. My business objects have static methods that just take LINQ classes and perform some calculation, say apply a certain states tax %, or w/e.
Since a lot of these calculations have to be done across the results of the repository I am thinking of combining them into one central area, like a facade layer, but one that just does transforms against the data and not translating to other objects sets (DomainObjects <-> DTOs).
Should I do that, or should I say that those business methods really are part of my model and that they should be in the repository methods that return the objects?
From a design standpoint I would design it like this. Of course naming is just for the purpose of this post you don't have to name your DAL and BLL ..Repository and ..Service.
Have repositories (or one) where your data access/queries should be happening. It should ideally just contain queries (compiled or not). I personally have a repository for each data type to help keep queries separated.
The next layer should be your business layer which I like to call services. These classes are responsible for all logic regarding validation, prep steps and anything else needed to be done to get the consumer of the service the information it needs. As with an ASP.NET MVC app I have my services return view models which are then directly passed into strongly-typed views. With my services I usually group them logically together instead of one for each data type.
This is a great design because it keeps your data access code and presentation code nice and thin and most of the logic where things can go wrong is in your service (or business) layer.

Resources