After my post last night, I got a brief introduction into how I might consider creating a three-tier+ structure from Twitter Luminary @Delebrin:
Considering I posted late at night and Delebrin responded shortly after, I didn’t see the response until the next morning at which point I drew this masterpiece for a followup:
Considering how long it took me to get to the point I’m at, deep-diving into the world of services.stuff was going to take some time since I really only know that “it exists”, but not the complete width and breadth of what it can do for me in the case of dependency injection. But as they say, even the longest journeys begin with a single step, so I set out to see what I could learn about Our Friend services.
I ran smack into a wall in only two online articles which set me to rights as it were. Although I did find a few other posts which explained how to create a solution with Separation of Concerns such that the presentation, business logic, and data layers are individual projects under the single solution, this one post disabused me of the idea that this was the way to go.
I’m not entirely sure how this trend started but I’ve seen some developers split an ASP.NET MVC project into multiple projects: a web project containing the presentation logic, plus two additional class libraries, often named [MyProject].BLL and [MyProject].DLL.Mosh Hamedani – https://programmingwithmosh.com/net/should-you-split-your-asp-net-mvc-project-into-multiple-projects/
I was thinking “this is what I want to do” until I read Mosh’s take on the matter, which boils down to this: don’t do it unless you have a use case where having different assemblies is going to get you some benefit.
I am used to creating single-package sites which contain the source code for presentation, business, and data layers. This generally works, but I’ve always thought that somehow there’s got to be a way that I don’t need to take down the site every time I need to make a minor update to compiled code. Couldn’t I just, you know, replace a DLL or something? I don’t know if this would work using three separate projects, each compiled to their own assemblies, but I never met a dead-end that I didn’t run into with wild abandon, so I had sold myself on the “one project per assembly” Separation of Concerns plan as the answer to a question I really don’t know how to ask.
Mosh presented the argument that reusability and deployability should determine whether to use a layered approach — creating logical divisions of code in a single project — or a tiered approach — creating “physical” separation via different projects. Although in a lot of cases shoving all source into one project “…under a folder or a class library like BLL and DAL does not immediately result in software with clean architecture and good separation of concerns…”, if having this source compile to DLLs that aren’t there to be reused, or aren’t there for deployability reasons, then there’s no good reason to do it!
He goes on to provide an example of an actual good reason, which completely resonated with what I’m trying to do. My project is a web-first project, so I’m using ASP.NET Core MVC to create that website. I could cram all my source — presentation, business, and data layers — into the project, and that would work as it always has, but what if I decided that I then needed a mobile application? I’d have to copy all of the business and data layer source into a new project, essentially splitting the code base completely. If there was a bug in the business layer of one, there would be a bug in the business layer of both.
Instead, a better way to handle it would be the include the business and data layers in one project, and the presentation in another. Using .NET Standard for my class libraries I still get portability between environments, which means I could write this single assembly to access a data source (data layer) and handle the querying and business logic (business layer) and inject it into whatever presentation layer I wanted to use it. In addition, if I decided that instead of hooking my web front end into the BLL/DLL directly through assembly dependency, I might write a web API that hooks into the BLL/DLL instead, and then update my MVC app to query that service. Then I could create my mobile app to also use that webservice. Regardless, having that 2/3s of the project as immutable as a programming project can be expected to be means I only have to switch up that 1/3 to “repurpose” the other 2/3.
So I think that’s what I’m going to do: one project for the presentation layer, and one project for the business and data layer. I will only need to worry about injecting my business layer into the presentation layer because the business and data layers would be co-habiting. Unfortunately this might mean that the need to use DI within that secondary project goes out the window, because if I ever needed to switch data storage back-ends I’d have to crack open the BLL/DAL project, duplicate it, and…well then I’d be right back at the same problem I’ve been trying to avoid.
Damned if I do, damned if I don’t.