The Coexistence of SOLID Principles, Clean Architecture and MVVM
Real world examples
Programming principles are essential for any programmer, but especially for senior developers that are setting the tone for the rest of their teams. You can find plenty of information regarding SOLID Principles here or here at freecodecamp. Clean Architecture puts some of this to practice here and a .NET implementation here that was recently updated to .NET 6.
If you aren't familiar with the above concepts I urge you to take a look at some of the links. It may help you in more ways than one. Regardless, there is power, longevity, and also assurance with code when keeping these concepts in mind. My perspective is the automation and steel industry. Many of my blogs will be centered around those concepts going forward.
Recently I have been tasked with helping to provide a framework for our development team for gathering and displaying data from logic controllers. If any of you are familiar with these concepts, they are basically state machines to harvest data. The last 10 years or so, I have been gearing much of my code around the SOLID concepts, but were never formalized. @UncleBob please take a look at my work below. I would enjoy your feedback. This portion is strictly a utility to take a data source (database, csv, xml, custom third-party formats, etc.) and allow the user to make some suggestive changes, and dump this data to a SQLite database.
The main application is called DataGroupImportUtility and it is small portion of the overall solution. Traditionally I have noticed that with clean architecture it is common to have many different projects defined. After some work this can be condensed down depending on project size. In my case, I decided on two, one or many UI's and another "Common" class library that can be used among many different projects. I would like to also note that when deciding these frameworks, it is important to be selective on your architecture with respect to your audience. There is no sense in implementing something elegant if your professional audience isn't up to speed. However you do have a responsibility to implement things in a fashion to provide VALUE. There is a delicate balance here.
The value here really lies in in overall future implementation of the project. Eventually there will be a WebApi, a front end, two running applications or services and maybe a couple of utilities. There will be scenarios where a shared library is important, but most importantly, through SOLID and Clean architecture, we are no longer supporting the project, but the future longevity of the value of the solution. Has it already scope creeped already? Not even scratching the surface. Let's dig in.
The folder structure
Consider the following folder structure.
Here you are see many different folders, but lets break it down. The following folders represent the "topic" or "feature" of the library. There are two folders currently, Import and Main. Main happens to support the actual data source AFTER import of the foreign data. So for instance, a user may have some foreign data that needs to be imported into the system. Main will represent the necessary interfaces to achieve CRUD's or other support into that data source. Not just from the Utility itself, but from other applications as well.
Next you will see the other topic/feature called "Import". Import will support all of the necessary functions for strictly the tooling to import foreign data. Aside from which topic we are in, notice that the folder structure follows the Clean architecture or represents a little bit of the "Domain-Application-Infrastructure Services pattern". Minus the Domain. We have a separate solution for that layer.
Daisy chain technologies
You can see in the screenshot that there is a folder in there for ViewModels. This location houses a view model that is really being used by the WinForms application. The view model implements all of the necessary services that both topic provide. Where we start to see the value here is that the WinForms application can be swapped out with WPF or MAUI, etc. The way that it was written allows for a controller consumption as well.
Consider the following overview.
You can see the foreign data boxes being consumed by the import utility interacting with the common dll that is implemented SOLID and Clean that is interacting with the database. You can also see then the Enterprise application interacting with the same dll using the verified database or data source. With the ViewModel approach, we aren't tied to WinForms, and with the SOLID techniques, we expose the potential for WebAPI Growth.
Ahmed Tarek's article here on when implementations affect abstractions has a couple of really good quotes.
" building knowledge about a system is a process. "
" The knowledge you gain from a system would benefit you on another system "
I agree with both of these statements because 3 months ago without the help of these principles, I would have only been incrementally better in this implementation. This system is a process and it does take time to let it evolve and rework. You can only foresee as much as you can, and the rest is left to doing the best that you can. However, the truth is that the flexibility that you can gain causes value for any company by using some of these techniques.
My apologies on the screenshot art. If anyone has suggestions on tooling for layouts and overall picture art, let me know. Next time, I want to get into some code on this same small section of the project to help illuminate what I have explained above.