In nlayerapp, the application layer and distributed services (distributed services) are on top of the domain model layer. The application layer is mainly responsible for receiving request data from the client, and then coordinating the domain model layer and infrastructure layer components to complete the semantic independence tasks; the distributed service department provides communication interfaces and technical architecture between the application layer and the client. It strictly says that it is not responsible for any task processing.ProgramIs a dispensable role: for ASP. NET web applications, it only needs to reference the interface of the application layer component, and then obtain the application layer component entity through IOC, without the support of distributed services. Of course, if you still need to consider integration with other systems, it is necessary to implement a distributed service. Today, we will first discuss the application layer in the nlayerapp. The nlayerapp divides the application service into three types: banking management, MERS MERs management, and sales management. This can be seen from the application. mainmodule. csproj project. In each application service, interfaces such as ibankingmanagementservice are defined for this service, and these interfaces are implemented using corresponding classes. In terms of structure, it is still relatively simple. This article will not introduce the specific implementation of each application layer service, but I still want to further discuss several aspects.
Constructor Injection)
The Implementation of the Application Service uses constructor injection to obtain the instance of the required object. For example, the constructor of the customermanagementservice class receives two parameters: the instance of icustomerrepository and the instance of icountryrepository. When the distributed service component uses iocfactory. instance. currentcontainer. when the resolve method is used to obtain the specific implementation of icustomermanagementservice, the IOC container automatically parses the dependencies of icustomerrepository and icountryrepository Based on the configuration information, so that when creating an icustomermanagementservice object, pass the parsed repository object to the constructor of customermanagementservice. You can find the dependency setting Code In the javaserootcontainer class of the iocunitycontainer class of the infrastructure. crosscutting. IOC. csproj project. For implementation of IOC containers in nlayerapp, see Microsoft nlayerapp case theory and practice-cross-cutting layer .
// register repositories mappings //... container. registertype
(New transientlifetimemanager (); container. registertype
(New transientlifetimemanager (); // Register Application Services mappings //... container. registertype
(New transientlifetimemanager ();
let's look back at the customermanagementservice class. Its constructor requires two parameters, icustomerrepository and icountryrepository, because the customermanagementservice class itself needs to use these warehousing objects for implementation. In fact, the implementation of the icustomermanagementservice interface does not require the implementation class to receive these two parameters. For example, if we have designed a mockcustomermanagementservice for testing purposes, it also implements the icustomermanagementservice interface, in this mock class, we use data structures such as dictionary and list to simulate the repository function. Therefore, in mockcustomermanagementservice, icustomerrepository and icountryrepository instances are not required. For example, our mockcustomermanagementservice can be implemented as follows:
Public class mockcustomermanagementservice: extends {private readonly list <customer> customerrepository = new list <customer> customerrepository; Public mockcustomermanagementservice () {} public void addcustomer (customer) {If (! Customerrepository. Contains (customer) customerrepository. Add (customer);} // other method implementations ...}
Then, in iocunitycontainer, change the code for registering icustomermanagementservice to the following:
Container. registertype <icustomermanagementservice, mockcustomermanagementservice> (New transientlifetimemanager ());
Data transmission object (DTO)
In the nlayerapp, domain entities are used as data transmission objects (DTO), and some DTO for specific purposes are also implemented, such as distributedservices. mainmodule. pagedcriteria in the csproj project. In application services, domain entities are processed as data transmission objects, which determines that domain entities must be used as DTO in higher-level distributed services. The reason is simple: distributed services do not convert DTO into domain entities, which is a task at the application layer. On the other hand, when the client generates the contracts proxy type, the WCF will block the disadvantages caused by the domain entity as a DTO, however, it seems that the client program of nlayerapp directly references domain entities for data exchange. From the perspective of DDD, this design is problematic. Of course, the specific situation should also be analyzed. In nlayerapp, most view models correspond to the structure of domain entities, and directly use domain entities as DTO reduces development complexity and productivity to a certain extent. NlayerappOfficial MaterialsThis problem has also been mentioned:
The latter case is when we use dtos (data transfer objects) for remote communications between tiers, where the domain model's internal entities wocould not flow to the presentation layer or any other point beyond the internal layers of the service. dto objects wocould be those provided to the presentation layer in a remote location.
If the implementation of the entities is stronugly linked to a specific technology, it is contrary to the DDD architecture recommendations because we are contaminating the entire architecture with a specific technology. however, we have the option of sending domain entities that are poco (plain old CLR objects), that is, serialized classes that are 100% M code and do not depend on any data access technology. in this case, the approach can be good and very productive, because we cocould have tools that generate code for these entity classes for is.
Thus, this approach (serialization of domain entities themselves) has the disadvantage of leaving the service consumer directly linked to the domain entities, which cocould have a different life cycle than the presentation layer data model and even different changing rates. therefore, this approach is suitable only when we maintain direct control over the whole application (including the client that consumes the web-service), like a typical N-tier application. on the other hand, when implementing SOA services for unknown consumers it is usually a better option to use dtos, as explained below.
Nlayerapp uses the serialized domain entities method. Now let's take a look at several key design points about DTO.
- DTO is designed for clients (including client applications and Web Services integrated with external systems). DTO is designed for client view models. The application layer is responsible for sending and receiving DTO data, and assembling DTO Based on the entities in the DTO data access domain model. Orm solves the impedance imbalance between the domain model and the relational database, while DTO solves the impedance imbalance between the view model and the domain model
- DTO should be poco, which cannot depend on any technical framework
- for small and medium systems, you can consider using serialized domain entities similar to nlayerapp, which can improve development efficiency. However, if it is a large system, we recommend using DTO, some people may think that it is time-consuming to design DTO Based on The View model. However, I think it would be better to design DTO based on a large scale of applications, in this way, system integration will be easier in the future. Dto design problems can be solved by using DSL and automated code generation technologies.
- the proxy data contracts generated by WCF is a DTO. If Microsoft is dedicated to the technology, there is no conflict with the second point, serialized domain entities can appear in the client program in the form of data contracts. To some extent, the negative effects of using serialized domain entities as DTO are blocked.
Coordination functions of application layer services on tasks
Many friends cannot understand the meaning of the application layer. They always think that the traditional three-tier architecture is the data access layer (DAL), business logic layer (BLL), and presentation layer (presentation ). The system architecture of nlayerapp shows the task coordination function at the application layer and its necessity. For example, the batch mtransfer method of bankingmanagementservice contains distributed transaction processing and repository and uow operations at the basic layer. The entire transfermtransfer method integrates these operations to complete a specific application task: to complete the transfer function. Generally, the Application Layer Code contains access to components at the lower layers. Therefore, the layers of DDD are not strictly hierarchical (the upper layer can only rely on its direct lower layer ). Of course, if your application does not need multi-layer coordination to complete a specific task, the application layer can also be omitted.
OK. I will discuss it here today. Next I will give a brief introduction to the distributed Services Section in nlayerapp.