Assemblies Architecture
Using our knowledge from the Functional Architecture chapter, let us define a structure of assemblies for a functional architecture that could natively support the deployment of a software product as a unit or as a set of microservices. Let us start our journey with a common use case of Person Registration and a Searching transition, which starts from the Initial state, to search for persons by first and last name. We will trigger this transition in a state handler located in the state logic layer and handle it in all three other layers such as the business logic layer, data processing logic layer, and data access logic layer using transition handlers. If you look at the following diagram, our task concerns its bottom part – the functional or business domain architecture:
As we learned in the Layered Architecture chapter, an assembly is a set of dynamic-link libraries (DLLs). According to the diagram, we need four sets of DLLs, one per logical layer.
First of all, we need one DLL per layer for handlers. Let's say our software product is dedicated to business process programming examples, and its abbreviation is BPP. Then we will have the following structure:
· State logic assembly
o BPP.Person.SL
· Business logic assembly
o BPP.Person.BL
· Data processing logic assembly
o BPP.Person.DPL
· Data access logic assembly
o BPP.Person.DAL
Next, we need to provide the non-functional architecture with the ability to register our handlers with it, so that the non-functional architecture can route requests to a specific handler according to the metadata in the data container. That is, each assembly must have a DLL responsible for registering handlers when the non-functional architecture requests such action. We can use the REG suffix for the names of the DLL that provides the handler registration service:
· State logic assembly
o BPP.Person.SL
o BPP.Person.SLREG
· Business logic assembly
o BPP.Person.BL
o BPP.Person.BLREG
· Data processing logic assembly
o BPP.Person.DPL
o BPP.Person.DPLREG
· Data access logic assembly
o BPP.Person.DAL
o BPP.Person.DALREG
Finally, we need a DLL that will contain string constants that are widely used across all logical layers and define the use case name, state names, transition names, data collection names, etc. Such a DLL is not part of any logical layer and sits above them, but is referenced by every DLL that contains handlers, resulting in it being included in every assembly anyway. Let's use the abbreviation CON in its name to emphasize that it contains constants:
· State logic assembly
o BPP.Person.SL
o BPP.Person.SLREG
o BPP.Person.CON
· Business logic assembly
o BPP.Person.BL
o BPP.Person.BLREG
o BPP.Person.CON
· Data processing logic assembly
o BPP.Person.DPL
o BPP.Person.DPLREG
o BPP.Person.CON
· Data access logic assembly
o BPP.Person.DAL
o BPP.Person.DALREG
o BPP.Person.CON
There is another DLL which is not formally part of any logical layer but is used in inter-layer communication and contains data transfer objects. As we know, a data container carries a set of strongly typed objects as data specific to a use case. Our use case concerns the functionality related to the Person entity. So, we need a DLL that exposes the Person entity to be included in the data container to transfer data about persons across logical layers. Each handler located at any logical layer will use this data to perform various activities on it. Let's use the abbreviation DTO in its name to emphasize that it contains data transfer objects:
· State logic assembly
o BPP.Person.SL
o BPP.Person.SLREG
o BPP.Person.CON
o BPP.Person.DTO
· Business logic assembly
o BPP.Person.BL
o BPP.Person.BLREG
o BPP.Person.CON
o BPP.Person.DTO
· Data processing logic assembly
o BPP.Person.DPL
o BPP.Person.DPLREG
o BPP.Person.CON
o BPP.Person.DTO
· Data access logic assembly
o BPP.Person.DAL
o BPP.Person.DALREG
o BPP.Person.CON
o BPP.Person.DTO
It's time to look inside the DLLs.
The state logic DLL BPP.Person.SL contains the state handler BPP.Person.SL.Initial, which handles activities related to the initial state of the Person use case.
The state logic registration DLL BPP.Person.SLREG contains the registrar BPP.Person.SLREG.Registrar, which registers state handlers located in the BPP.Person.SL DLL with a non-functional architecture.
· State logic assembly
o BPP.Person.SL
§ BPP.Person.SL.Initial
o BPP.Person.SLREG
§ BPP.Person.SLREG.Registrar
The business logic DLL BPP.Person.BL contains the transition handler BPP.Person.BL.Searching, which handles activities related to the Searching transition of the Person use case.
The business logic registration DLL BPP.Person.BLREG contains the registrar BPP.Person.BLREG.Registrar, which registers transition handlers located in the BPP.Person.BL DLL with a non-functional architecture.
· Business logic assembly
o BPP.Person.BL
§ BPP.Person.BL.Searching
o BPP.Person.BLREG
§ BPP.Person.BLREG.Registrar
The data processing logic DLL BPP.Person.DPL contains the transition handler BPP.Person.DPL.Searching, which handles activities related to the Searching transition of the Person use case.
The data processing logic registration DLL BPP.Person.DPLREG contains the registrar BPP.Person.DPLREG.Registrar, which registers transition handlers located in the BPP.Person.DPL DLL with a non-functional architecture.
· Data processing logic assembly
o BPP.Person.DPL
§ BPP.Person.DPL.Searching
o BPP.Person.DPLREG
§ BPP.Person.DPLREG.Registrar
The data access logic DLL BPP.Person.DAL contains the transition handler BPP.Person.DAL.Searching, which handles activities related to the Searching transition of the Person use case.
The data access logic registration DLL BPP.Person.DALREG contains the registrar BPP.Person.DALREG.Registrar, which registers transition handlers located in the BPP.Person.DAL DLL with a non-functional architecture.
· Data access logic assembly
o BPP.Person.DAL
§ BPP.Person.DAL.Searching
o BPP.Person.DALREG
§ BPP.Person.DALREG.Registrar
The DLL with constants BPP.Person.CON contains the following components:
· BPP.Person.CON
o BPP.Person.CON.DataCollectionTypes
o BPP.Person.CON.EventTypes
o BPP.Person.CON.StateTypes
o BPP.Person.CON.TransitionTypes
o BPP.Person.CON.UseCaseContract
The DDL with data transfer objects BPP.Person.DTO contains the following components:
· BPP.Person.DTO
o BPP.Person.DTO.PersonDTO
o BPP.Person.DTO.PersonSearchDTO
And that’s it. As a result, we have ten DLLs belonging to the Person use case and logically grouped into four assemblies, where each assembly serves the functionality of a specific layer. This structure allows us to develop the functionality of each use case and each of its layers independently of any other use case or logical layer of the use case. This structure allows us to deploy all the DLLs as a single deployment unit or deploy them as a set of four microservices. That is, by implementing the above structure, we will reach another our fundamental goal – deployment-agnostic software development.
Table of Content Software Architecture Previous: DNS Server Role