ASP.NET MVC3 - 3-Tier Design - Transaction Management and Business Tier Issues

I am developing an ASP.NET MVC3 application, and I would like to have a clear separation of problems in a three-layer architecture. I use Fluent NHibernate as ORM, a repository pattern for working with objects displayed by NHibernate. I would like to add the correct business layer with the Unit Of Work template, saving part of the MVC for presentation only (using ViewModels that map to nHibernate objects through the business layer). This article describes well the combined 3-tier and MVC architectures.

According to this MVC + unit of work + repository in the article, I do not see a clear difference in the business level. A working class unit represents strongly typed getters for each type of repository that looks appropriate for the business layer. However, it provides a Save method, which I think will translate into BeginTransaction and CommitTransaction methods with nHibernate. This raises some questions:

1) Does MVC transaction management provide a good idea? At what stage should transactional management take place? It seems to me that MVC should not be responsible for transactions, but how to avoid this?

2) Should there be some kind of automatic way of processing transactions? This implementation of ActionFilter is semi-automatic, but transaction management is clearly located in the MVC section, which is not a business layer.

3) Is the UnitOfWork class the same as the business layer class?
- if this is so, does this mean that we can add our own business logical methods to it?
- if not, are we wrapping the unit of work with some other classes that contain business logic methods?

I appreciate any ideas or examples. Thanks.

+6
source share
3 answers

First of all, I want to clarify a small incorrect concept of the business layer, since you want to use the repository template, and your setup is a candidate for Domain Driven Design , then the business layer is [Domain model ( Objects and objects of value , where you develop your business logic in an object-oriented style in objects and objects) and Application Layer for coordinating transactions and operations and commands at the domain level], so the proposed architecture will be something like this:

  • Presentation (MVC) [OrderView, OrderPresentationModel, OrderController]
  • Application [OrderService]
    • Use UnitOfWork (transactions) and Repositories to execute domain logic
    • DTOs [OrderDTO, CustomerDTO]
  • Domain
    • Objects and objects of value [Order, Customer, Linear address, Address]
    • Repository Interfaces [IOrderRepository, ICustomerRepository]
    • (optional) Working Interface Interface [IUnitOfWork]
  • Infrastructure.DataAccess (using ORM technology or data access)
    • Repositories [OrderRepository, CustomerRepository]
    • (optional) Unit of work [UnitOfWork]
  • Infrastructure.Common
    • entrance
    • Utilities

Example script:

[Presentation] OrderController:

_orderService.CreateOrder(OrderDTO); 

[Application] OrderService:

  _unitOfWork.BeginTransaction(); var customer = _customerRepository.GetById(orderDTO.CustomerId); var order = new Order() { Customer=customer, Price=orderDTO.Price, ... } _orderRepository.Add(order); _unitOfWork.Commit(); 

About your questions:

1) Does MVC transaction management provide a good idea? At what stage should transactional management take place? It seems to me that MVC is not responsible for transactions, but how to avoid this?

No, I would prefer to split it at the application level to make the design flexible to support various presentations.

2) Should there be some kind of automatic way of processing transactions? This implementation of ActionFilter is semi-automatic, but transaction management is clearly located in the MVC section, which is not a business layer.

Use application level transactions.

3) Is the UnitOfWork class the same as the business layer class? - if so, does this mean that we can add our own methods of business logic to it? - if not, are we wrapping the unit of work with some other classes that contain business logic methods?

No, this is just a way to group tasks into transactions. Business logic is actually encapsulated in an entity, and if the logic is not associated with one entity, it must be implemented in the services of the domain [TransferService.Transfer (account1, account2, amount)], for approvals, access to repositories and transactions, the application layer is the place .

+12
source

Have you looked at S # arp Architecture ? It has built-in MVC transaction processing using Action Filters.

I am usually a purist, so I was not thrilled to let MVC open the show, but I liked it.

There is pro and con, but here are some of the advantages of having a session open in a view. :

  • Lazy Loading - This will make it easier to access data if you can rely on lazy loading in your MVC views. There is no need to explicitly join all the tables required by the view. (Be sure to avoid the N + 1 problem by joining explicitly when lazy loading will cause an absurd amount of requests. Data referrals are a common criminal here.)
  • Simplified BSO Level - Your BSO does not need to worry about sessions. He suggested that you are already working in a session context.

If you don't want to go with S # arp, you can still implement Open-Session-In-View yourself, with only a few lines of code in the ActionFilter. In the "Action" section, complete the session. The action executes the method, commit, close and delete. This is what we do in my project, and it worked well for us.

+1
source

The problem that you work with in any web application is that you need to associate the user interface with the buisness layer because of the need to control the lifetime of the object using an HTTP session. In a typical desktop application, you don’t need to worry about sessions, so this makes it easy to move the entire transaction along the chain.

Consider where you want to use the same logic in three applications: a website, a web service, and a desktop application. Without subjecting transaction processing to the presentation layer, there is no good way to handle transactional commits, since the business layer does not know how long the objects will exist.

Thus, your choice is to make sure that you do everything in each method of your business objects or expose a transaction in the user interface.

A third alternative would be to create a rather sophisticated session management controller that I don’t even want to think about ... Session management controller can be connected with ui and business logic, separating them to some extent .. But this will require much more analysis.

0
source

Source: https://habr.com/ru/post/899326/


All Articles