The Micro-service Base Class Libraries: BlueprintsPublished: July 18, 2016
As stated in the previous post: I set out to create a model of a micro-service for an organization trying to create a more SOA for their applications. I started off by creating a quick template, but found my code repeating itself and hoped to extract repetitious parts.
The two projects I plan on talking about first are the Contracts projects.
Contracts.csproj: This project contains the objects and interfaces that are exposed externally from this Api.
DataAccess.Contracts.csproj: This project contains all of the objects and interfaces that are exposed externally from the DataAccess project.
If one were to look at a service-oriented architecture(SOA), they might break it down into pieces as follows: User Interface(UI), Business Logic Layer(BLL) and Data Access Layer(DAL). Attempting to relate this to a building’s architecture, one might ask, to what do each of these pieces correlate? The UI could easily relate to either the interior or exterior design of the building. The foundation could be associated with the DAL as it is the part that is most hidden from the user, but plays a very critical role in the usefulness of the application to the user. The BLL could be the structure of the building: the supports and skeleton of the building. It reaches into the foundation, but then spreads-out and provides the strictures within which the rest of the building must adhere. The micro-service architecture described in the last article contained a few other projects as well.
There were the test projects and the contract projects. The test projects could be likened to the modeling aspect of a building project. Either computer modeling or actual physical models as they are created to prove out an architect’s concept of what a building would or could be. I like to think of the Contracts projects as the blueprints for the building. Once the concept of the building has been solidified, it is time to create a blueprint of what the building should look like. Once this aspect of the building project can be committed to paper, the myriad other aspects that are involved in the building project can begin. When designing the aesthetics of the building, without knowing the exact dimensions of the building or where exactly the supports need to go, it is difficult to have an exact design. One could have a concept for a design, but it will have to adhere to the blueprint to become a reality.
In defining any new software project, I find it is very useful to first talk about the Contracts. Where are the seams of the application going to be and what exactly should those look like? What objects are going to be encapsulated and represented through this application? What are the interactions that are going to be allowed to occur with these objects through this application and how are those interactions going to take place?
This particular organization, for a variety of reasons, has historically dealt with most of their data in such a way that the current state of the system is saved in the database, but the previous states of the system were discarded when an update was made. This has proven over time to be a very unfortunate state of affairs as reporting has become much less useful than it could have been. There has been a very concentrated effort as of late to change this state of affairs. With that in mind, at a bare minimum, we would like to track some audit information on all of our objects. A relatively easy, but potentially naive approach as well to obtain a way of tracking historical data, is through the use of valid from and thru dates. I believe there is a potentially better approach which was suggested in an MSDN article that I’ve created a project around, but that will have to wait for another post as that was outside of the scope of this particular project.
As can be seen in this pull request, the fields mentioned above were extracted and placed in two base classes, since they are going to be repeated throughout the micro-services. The lowest level base class contains all of the properties mentioned above excluding the valid from/thru dates. While these could be valid on every object in the system, there were a few where it seemed like overkill. The example project contains countries and country subdivisions(i.e. states in the United States of America or provinces in Canada). While there are some countries that these concepts can be a little more fluid than others, the company this project was for, operated mostly in the United States where these concepts remain pretty consistent(rumors of Texas succession not withstanding). So for those rare instances where tracking valid from/thru dates don’t seem so applicable, the IdBase class was created. The IdBase class was made generic mostly to enable the classes to either have an integer or a long as their id. While other types are allowed technically through the code, the conventions of the organization were to use one of those two types.
After talking about the objects that are going be encapsulated in this project, it would be nice to also discuss the avenues of interaction with these objects that the service is going to provide as well. Again, since this service was just serving to demonstrate the need for and usefulness of the base class libraries, I didn’t create all of the objects that the service would most likely expose, but just a few to utilize as examples and as a safety net to enable testing throughout the refactoring process. As can be seen in the interfaces contained in the Contracts projects, there is a very small surface area for these objects, but it provides all of the functionality that is needed for basic operations to take place regarding these objects. It is also easy to maintain a consistent surface area for all of the micro-service encapsulated objects in the system if these conventions are adhered to. There is one other method that I think would be useful to expose which is a search/find/filter method that would allow the user to create a more complex set of matching criteria in which to utilize to find objects that fit those criteria. That again was a bit more work than what was in scope for this project, but I hope to make a post out of it later as well.
As you can tell, the refactoring changes that were made to the DataAccess.Contracts project were very similar in nature to the ones described above. One might reasonably ask, why have two different Contracts projects? In looking at the two, they seem to have a lot of overlap. While this is true, I often find it very useful to make the seams of the application very clear and well defined. While I believe this is sufficient justification alone, you can also see in the current state of the application where these two sets of contracts deviate from one another. The DataAccess.Contracts have some special nomenclature and attributes relating to Entity Framework. They are only applicable at the DAL layer and not exposed above. Also, depending on how the organization ultimately wants to structure its applications, building and deployment processes, having the interfaces in this project would allow for the organization to switch out the underlying implementation of the DAL with a very minimal build/deploy process.