Using seperate layers for interfaces and DTO's - oop

I'm currently following an IT study, and we're asked to use interfaces and DTO's in a multi-layered ASP.Net Core MVC consisting of Presentation, Logic/Business, and Data Access, using dependency inversion so that both the presentation and DAL have references to the logic layer. In between the Logic and DAL, we have to use DTO's and Interfaces. I understand the concepts of both, and I know how to use them. However, we can decide for ourselves whether we want to create seperate layers for our DTO's and Interfaces, or to stick them in the logic layer. We are also asked to explain why we chose one option over the other. However, I cannot find any sources for why you would pick one over the other anywhere. So that's why I'm asking here.
So my question is: What are the advantages and disadvantages of putting your DTO's and Interfaces in a seperate layer, and what are the advantages and disadvantages of just keeping them in the logic layer?
Thanks in advance.

What are the advantages and disadvantages of putting your DTO's and Interfaces in a separate layer
I imagine separate layer like this:
Core
|
------------
| | |
DAL BLL PresentationLayer
Advantages are:
can be used in any other layers. So each layer can expose own dto by its API,
but internally it uses own classes. E.g. data layer can use internally own model clases Person,
however data layer returns PersonDto to Business Layer
you can easily reference this separate layer into other layers without forcing to introduce unnecessary
dependencies. E.g., if application is using just one model from data layer, then you will have to reference
this layer into presentation layer.
Disadvantages:
recompiling? If you edit your dto, then you need to recompile your layer and recompile all layers that
depepnds on this layer
what are the advantages and disadvantages of just keeping them in the logic layer?
Advantages:
I do not think that this approach has any advantages
Disadvantages:
wheneever you want to use dto or interface in any other layer, you have to reference the whole
this logic layer. This logic layer can expose unnecessary API for this layer.

Related

Strategy for Sharing Business and Data Access Entities

I'm designing a layered application where 90% of the business and data access entities have the same properties. Basically it doesn't make sense to create one set of classes for each layer (and map) with the same properties for the sake of separation of concerns. I'm completely aware of automappers but I'd rather not use one in this case as I think it's unecessary. Is it ok to share share the business entities between the business and data access layer in this scenario? We will manage the remaining 10% of the classes by creating adhoc/transformed classes within the same namespace.
Any other design approach?
I think sharing between layers is the whole point of having model classes backed by a data store. I would avoid adding unnecessary architecture unless the code really needs it. If you get to a point where you need to be agnostic of the data store or some other similar situation, I would you might look into the Repository pattern. Simple code = maintainable code.

Data Access Layer - Utility classes and data transfer objects

I have a book, which talks about design patterns and the use of layers in particular i.e. presentation layer, business logic layer and data access layer.
I now understand the concept of a utility class and a data transfer object. However, all of the examples and information in the book talk about how they apply to the business logic layer.
I assume that they also apply to the data logic layer as well or is there another design pattern that I am unaware of?
This question follows on from a question I asked yesterday, here: VB.NET - Creating objects on every loop.
I will post some code to clarify what I am asking if required, though this is more of a conceptual question.
Utility classes and DTOs are equally at home in the data and presentation layers. I often use DTOs defined in the data layer to pass data "up" to the business layer.

where should I do the conversion: Domain object<->DTO?

In Domain Layer or Data access layer?
The primary motivation for DTOs is to present an interface tailored to another layer (typically, the presentation layer). For example, a data entry screen may need some bits of data from a User object in addition to some bits from an Order, etc. In that case, the Domain to DTO should happen at the layer which the presentation layer invokes, i.e., typically a "service" layer.
There are libraries like Dozer out there which automate the grunt work of converting between domain models and DTOs.
The key take away is DTOs are meant to abstract the data (not business logic) out of richer domain model objects - hence, DTOs should be converted back to domain objects as early as possible (at service layer) so the rest of your application layers may work with richer domain objects (data and business logic)
I'm not much of a fan of DTOs, but I say don't do it in the data layer. The data layer deals with model objects and their persistence. Why couple it with other layers by bringing DTOs into it? I'd map them somewhere else, probably between the service and ui tiers, just at the point where they cross the boundary between where they're created and where they're used.
Putting this in MVC context, if you have both controllers and services layer you should put it in the controller. This would make a DTO closer to the view layer and allow the service layer to play with domain objects only, avoiding possible confusion with other models.
The DTO itself is actually the MVC model (Explained here: https://stackoverflow.com/a/1058186).
Below is a recommended tutorial that mashes the controller, service layer and DTO concepts together (In java using Spring framework, but the concept is clear for other platforms as well):
https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

Repository pattern and Business logic

I have a repository (CustomerRepository) that retrieves data from the data layer. Most of the business logic is in the entity class (Customer) that the repository either accepts or returns.
However, where do you put the global entity business logic (that applies to all customers)?
For instance, I may not want to return all customers to certain users. I don't want to put that logic in the repository.
I agree with Robert Munteanu.
Basically you roll up your business logic that isn't inherent in your model into a middle tier. The middle tier is the business tier / business objects / business logic layer / etc, but is just referred to as a service tier. It doesn't have to be a webservice, its a broad use of the term service in that it aggregates functionality of a specific application area.
You would basically have a CustomerService class that contains the repository reference. Your presentation layer would reference the service layer class.
There is an additional distinction that can be made as a guess from your name you are using .net, and probably using LINQ to SQL as your repository as outlined in NerdDinner.
The Repository typically returns IQueryable to the service layer, allowing the service layer chain together multiple queries to build different result sets. The Service then evaluates the expression using ToList or another similar method and returns that to the presentation layer.
Put it in another repository (BusinessRuleRepository) and have CustomerRepository use it.
OR
If the business logic is only limiting the results a user can see you might want to use a Facade pattern with a factory. In this case you would have an ICustomerRepository that handles your CustomerRepository and LimitedCustomerRepository (which might encapsulate CustomerRepository), and a CustomerRepositoryFactory that returns the appropriate ICustomerRepository for the user.
Wrap it behind a service.
I think separating these types of functions into a service layer is the way to go.
I recently built a system to do complex forecasting with many entities using historical data. Putting all the data access bits in the repository for each entity. The intricate forecasting logic I kept in a service layer and passed the repository objects in as needed.
Added bonus was that I had an easy way to expose all the forecasting logic to external systems by simply creating a web api layer.

How should business level objects be named?

We are building a service-oriented system where we have separated the application into several layers:
SOAP web services (e.g., BuildingService.asmx)
Business logic layer (e.g., BuildingXXX)
Data Access layer (e.g, BuildingProvider)
Types (e.g., Building)
The SOAP web services simply instantiate an object of type BuildingXXX from the business logic layer in order to keep the implementation out of the SOAP web services. BuildingXXX then uses the BuildingProvider from the data access layer to return types defined in the data transfer object layer.
We have been unable to determine what we should call the objects in the business logic layer.
What is the "standard" naming convention for naming these business level entities?
Personally, I would call your business logic layer services "BuildingService" then call the web services "BuildingWebService".
Or you could always go with the generic "BuildingManager" as well for the service layer..
Namespaces are your friends. How about BusinessLayer.Building, BusinessLayer.Facility? Use DataLayer.Building, DataLayer.Facility, etc. You get to call things what they are, yet they get to be different things.
I would naively go with BuildingRules (since this is what they are, right?) but then I don't actually know what are the conventions...
i prefer prefixes instead of suffixes, so that the related layers sort together, e.g.
BizRuleBuilding,
BizRuleFacility,
...