Let's say you have three models, Organization, OrganizationUser, and User.
You need to handle the following reqs:
When a user creates an organization, they should become a user associated with that organization (a row in OrganizationUser table).
If any of the operations above fail, the entire "flow" should fail. This should be implemented with a transaction.
Here are the three best ways I think you can architect it:
In the controller, create TXN, pass it to the Organization and OrganizationUser models to create their respective rows. Rollback if needed. Controller contains the business logic (has user paid, what type of org... etc).
In the controller, call CreateOrganizationService which handles the transaction creation, abstracting it away from the controller; passes it into the models. CreateOrganizationService is where we'll keep most of the business logic
Have Organization model require OrganizationUser model and take care of the transaction creation, the business logic, and creation of the OrganizationUser row.
Is there a better way of thinking about this, or different approaches/patterns I can apply?
The Controller's job is to translate incoming requests into outgoing responses. In order to do this, the controller must take request data and pass it into the Service layer. The service layer then returns data that the Controller injects into a View for rendering.
The model in MVC is not a class, it's a layer.
The Model's job is to represent the problem domain, maintain state, and provide methods for accessing and mutating the state of the application. The Model layer is typically broken down into several different layers:
Service layer - this layer provides cohesive, high-level logic for related parts of an application. This layer is invoked directly by the Controller and View helpers.
Data Access layer - (e.g. Data Mapper) this layer provides access to the persistence layer. This layer is only ever invoked by Service objects.
Value Objects / Entity layer - this layer provides simple, data-oriented representations of "leaf" nodes in your model hierarchy.
To your question: Don't put business logic or transactions into the controller. Put the business logic (and transactions) stuff into the Service class (part of the model layer).
Source
You can implement a service layer in between controller and repository where you can handle the business logic and making the controller clean. And all the operations related to database (CRUD) can be done in repository.
Refer this :
Difference between Repository and Service Layer?
from your controller, you can call:
svc.CreateOrganization(<params>);
I probably wouldnt pass the model into the service. I would pass the actual data parameterized out for each piece of data b/c inside of your CreateOrganization call you should be calling into the data access layer which should use DAOs to store data.
Related
I'm building a .NET Core MVC application. It has a single endpoint that retrieves an imdb id of a movie by scraping the imdb site. So my question is, where do I put the logic to get the id? My original project structure is shown below.
+--Controller
+--Entry point api call
+--Logic
+--Class that retrieves imdbId
+--Models
+--Models
+--Context
So I was originally going to put the logic where it retrieves the id in the "Logic" folder and call it from the Controller. I was also going to instantiate the model and store it in the DB here. I also do request validation in the controller and make sure the given movie title and release year are correct format.
I'm starting to think this is incorrect though? Should I put request validation and id retrieval in the model layer? Any help on how to approach this would be appreciated.
So I was originally going to put the logic where it retrieves the id in the "Logic" folder and call it from the Controller.
This is what I would do too. ID retrieval is not a concern of the controller (the presentation layer does not care how you retrieve the ID) so it should be placed in a separate layer.
Should I put request validation and id retrieval in the model layer?
No, because this does not pertain to the models. The model layer should just contain the classes for your models. I would put request validation in the controller (presentation layer).
My suggestion is that your original project structure works fine. Within the logic layer, I would further separate concerns among different services, so that the ID retrieval functionality would reside in a separate service from the DB storage functionality (DB management could also be a separate layer on its own).
I would suggest you put it in the Logic class, so you can unit test the logic outside of the model. Your models should be super simple, just properties, and if there is some other internal logic they need.
The http call you will need to make I would put in your logic and ensure you are using some interface for your http client so you can create moqs for easier unit testing.
We are creating rest api's with Spring Boot. We have three layers in our project(Repository, Service and Controller).
Lets say I have GetUser api in my controller that return UserDTO object.
#GetMapping
public UserDTO getUser() {
return userService.getUser();
}
Whether userService.getUser() returns UserDTO object or it returns User object and it is converted to UserDTO object in the controller? Which one is better way?
Shortly, domain object to DTO object conversion, should be done in service layer or controller layer?
I think there is no "better way" for converting your domain objects to your DTO objects, it's a matter of taste. In my projects I convert the domain objects to the DTO in the service layer as part of my "business logic". So you reduce the accessability of your domain objects only to your service layer. Furthermore I want to reduce the "logic" inside my controllers as they are part of the application layer.
PS: If you are looking for several ways to convert your domain objects to your DTOs have look at one of my latest Stackoverflow questions (How to properly convert domain entities to DTOs while considering scalability & testability)
It depends on application needs and architecture. Idea is to keep dto conversion at edge. It is generally prefer to have dto and domain conversion at the controller level. If you want to keep services/business logic independent of consumer, then it is always better to have at api level. This becomes more clear if your service has been consumed by more than one consumer.
In my experience, the conversion should be on the Controller layer. This gives an advantage that able to reuse other service methods with the return object is the origin.
This point may be important sometimes because the DTO object often reduce fields from the origin object. Therefore, we need more code to get these reduced fields, making our code ugly and duplicated.
I know that it would be moving logic to the controller layer, but it is a tradeoff.
Here is what I do in general:
My service layer takes dto as an argument.
I do the conversion at the service layer, because I might need to apply some business logic when converting.
But my service layer always returns entity. And I do the conversion at the controller level. This makes my service is clean and independent of the consumer. It may happen that my service might be consumed by another service and need entity not the dto.
In summary:
Dto —> Entity (Service layer)
Entity —> Dto (Controller layer)
I have the following design :
My Design
My Design http://s15.postimg.org/3zha8rzqh/Design_Idea.png
I will have a class called 'ProductDTO' in my service layer (the left service).
When the 'Update Product ( ProductDTO )' operation contract is called - it should call the 'Update Product' function in the Business Logic Layer.
In the database (the 'Data Access Layer') there is an entity called 'Product', and because I use LINQ-To-Entities I will also have a class there called 'Product'.
My question is - where do I translate from 'ProductDTO' to 'Product' ?
Should I have a 'Translate_ProductDTO_To_Product' function in the service layer ?
It seems the most logic answer, because that is the only layer that knows what 'ProductDTO' is.
But this means that the service layer will also have to know what 'Product' is, and thus will have to reference the data access layer assemblies.
Is this correct ?
I thought that the service layer should only reference the business logic layer, and that the business logic layer should only reference the data access layer, and that the service layer should know nothing about the DAL.
It seems your confusion may stem from assuming the Product class in your data layer is actually the Product entity. Generally in domain driver design, your business entities live-in/are the business logic layer. Usually these class are "ignorant" of persistence which is the responsibility of the data access layer (typically using an object-relational mapper framework).
In practice, your service will require references to both to the domain model (business layer) and the data access layer to perform useful work. Both the WCF service code and the data access layer should depend on the domain model but the domain model should not have dependencies on either the data access layer or the WCF service code.
Map the DTO to your domain entities in your service layer. Your service layer needs to know about DTOs and the entities it is mapping to (and from). I strongly advise you use a tool like AutoMapper to do the mapping rather than hand-crafting.
Your service layer should not reference your DA layer (or assembly). Your BL later will need to reference your DA layer to persist the entities.
Edit:
Your business entites probably should not be under a DA namespace. If you are using an ORM tool to generate them, make sure you put any DDD logic in the other half of a partial class.
I am creating a brand new application, including the database, and I'm going to use Entity Framework Code First. This will also use WCF for services which also opens it up for multiple UI's for different devices, as well as making the services API usable from other unknown apps.
I have seen this batted around in several posts here on SO but I don't see direct questions or answers pertaining to Code First, although there are a few mentioning POCOs. I am going to ask the question again so here it goes - do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries? I am really trying to follow the YAGNI train of thought so while I have a clean sheet of paper I figured that I would get this out of the way first.
Thanks,
Paul Speranza
There is no definite answer to this problem and it is also the reason why you didn't find any.
Are you going to build services providing CRUD operations? It generally means that your services will be able to return, insert, update and delete entities as they are = you will always expose whole entity or single exactly defined serializable part of the entity to all clients. But once you do this it probably worth to check WCF Data Services.
Are you going to expose business facade working with entities? The facade will provide real business methods instead of just CRUD operations. These buisness methods will get some data object and decompose it to multiple entities in wrapped business logic. Here it makes sense to use specific DTO for every operation. DTO will transfer only data needed for the operation and return only date allowed to the client.
Very simple example. Suppose that your entities keep information like LastModifiedBy. This is probably information you want to pass back to the client. In the first scenario you have single serializable set so you will pass it back to the client and client pass it modified back to the service. Now you must verify that client didn't change the field because he probably didn't have permissions to do that. You must do it with every single field which client didn't have permission to change. In the second scenario your DTO with updated data will simply not include this property (= specialized DTO for your operation) so client will not be able to send you a new value at all.
It can be somehow related to the way how you want to work with data and where your real logic will be applied. Will it be on the service or on the client? How will you ensure that client will not post invalid data? Do you want to restrict passing invalid data by logic or by specific transferred objects?
I strongly recommend a dedicated view model.
Doing this means:
You can design the UI (and iterate on it) without having to wait to design the data model first.
There is less friction when you want to change the UI.
You can avoid security problems with auto-mapping/model binding "accidentally" updating fields which shouldn't be editable by the user -- just don't put them in the view model.
However, with a WCF Data Service, it's hard to ignore the advantage of being able to write the service in essentially one line when you expose entities directly. So that might make the most sense for the WCF/server side.
But when it comes to UI, you're "gonna need it."
do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries?
Yes, the same set of POCOs / entities can be used for all boundaries.
But a set of mappers / converters / configurators will be needed to adapt entities to some generic structures of each layer.
For example, when entities are configured with DataContract and DataMember attributes, WCF is able to transfer domain objects' state without creating any special classes.
Similarly, when entities are mapped using Entity Framework fluent mapping api, EF is able to persist domain objects' state in database without creating any special classes.
The same way, entities can be configured to be used in any layer by means of the layer infrastructure without creating any special classes.
In Building a Desktop To-Do Application with NHibernate, Oren Eini (a.k.a. Ayende Rahien) shares that the general recommended NHibernate practice is to use one session per form in a desktop application. In the example given, this is easily implemented because the form presenters have knowledge of the persistence layer and so can create and dispose of sessions to match their life cycles.
In a more complex application, a service/business logic layer (BLL) usually sits between UI code and the persistence layer. The UI layer knows nothing about persistence (or sessions). In such a case, how does one (or does one?) maintain one session per form ?
Thank you,
Ben
The service layer will still get a session injected, either directly or by using a current session context.
You might think about using the MVC architecture, popular in web applications, where the controller deals directly with the domain model and the NHibernate sessions rather than delegating business logic to a business logic layer. The controller can maintain its own sessions however it likes.
It depends. In complex applications when using service oriented architectures the Nhibernate Session is generally tied to the service's session model.
You should decide wether the service layer will be requiring sessions to the desktop clients or not, and implement sessions in nhibernate following the service needs.