7

I've been working with C# and .Net Framework for a little more than 1 year. When I arrived on this project, there was already someone who laid the solution/projects structure and his approach was "separation of concerns" oriented and I tend to agree with him on this one.

But recently we asked some contractors to work on a separate part of our project. And their approach seems to be a bit more "namespace" oriented. To be clear, they've created way more projects within the solution that I'd have expected.

Seeing this I started to look into the microsoft documentation to check if there was some kind of guidelines on when to create a project within a solution, but so far all I found was : "Solution is a container of projects, here is how to create a project..."

So I was wondering if anyone would share its expertise on this or if I missed some documentation on my research of guidelines.

5
  • 1
    I'm not looking for internet points, but I guess that people that are down voting this could at least provide some kind of reason ?
    – MaxouMask
    Jun 17, 2020 at 10:12
  • 1
    Projects are compiled separately and generates seperate assemblies. So if you have code used by multiple projects and solutions, or it needs to be seperately deployable, it have to be in a separate project. If you use multiple .net languages, it has to be in separate projects also since each project is compiled as a unit.
    – JacquesB
    Jun 17, 2020 at 10:13
  • 2
    Basically namespaces are logical separations, while projects/assemblies are build-related and physical separations.
    – JacquesB
    Jun 17, 2020 at 10:24
  • 1
  • @DocBrown: Thanks I will take a look to that.
    – MaxouMask
    Jun 17, 2020 at 15:19

1 Answer 1

10

In the scope of your specific focus, projects are separate build steps, allow you to reuse parts of your domain in other parts of your domain, allow for individual versioning, and enforce a one-directional dependency graph.

Each project will be compiled into its own DLL. If project B depends on project A, then when you build B, you're going to build A; after which B can be built using A's dll.

So why does that matter?

If you are building one monolithic application, it doesn't technically matter in how many sub-projects you split this codebase in. I'm not saying it's good practice, and I definitely am not advising you to do it, but in such a situation the benefits of project separation simply don't really provide a benefit other than allowing you to neatly group your classes, which you could technically also be doing via folders in your single monolith project.

The benefits of project separation begin to show themselves when you move away from the monolith example.

If you are building multiple applications (e.g. a web api and a winforms app), then you're definitely going to need to have at least two projects, as the build process for either of these is completely different.

More importantly, suppose these two applications are expected to use the same business logic. Rather than copy/pasting that logic in both projects, it makes much more sense to create a third project to represent the business logic, and have your web api and winforms projects depend on that business logic project. This allows you to reuse your logic in different consumers.

When you iteratively apply this process of creating new projects for reusable logic, you will end up separating each layer into its own project (at the very least). But you're probably going to end up with even more projects, e.g. when you separate your interface from your implementation (which is commonly split into separate projects), or your test suites, or ...

You could conclude that a project's purpose is defined by it being consumed by more than one "parent" project, but do keep in mind that this is a bit too strict to be a complete definition. Even if there's currently only one consumer of your business logic, it's still valuable to already split this off into a project of its own.

Good practice includes preparing for the future - but I suppose you could then also say that even better practice is being able to reasonably judge which preparations are warranted and which are overkill. As far as project separation goes, you should err towards it being a warranted preparation for future code flexibility.

If you ever decide to create a second consumer, you won't have to start the cumbersome process of separating the business logic from what is now considered the "first consumer" of that business logic. It's much better to have it separated from the start. This is why developers often generate projects for every layer in their codebase, as a first approximation of how the code can be built with reusability in mind.

Another benefit to using projects (as opposed to folders) is that you can enforce dependency order. When dealing with projects that depend on each other, it's impossible to create circular dependencies. If A depends on B, then B cannot also depend on A (if they do, then either you're doing something very wrong or they should really be one joined AB project).
Had you been using folders to separate your classes, then there would've been no protection against circular dependencies, class A can refer to class B which in turn can refer to class A.


So, to summarize:

  • Projects maximize library reusability when there are multiple consumers (now or in the future)
  • Projects are individually built and can be versioned as such
  • Projects help you to enforce a one-directional dependency graph

So when should you create an extra project?

The correct though tautological answer is "when it's appropriate". In other words, when one of the mentioned benefits apply to your scenario.

And I just want to repeat here that good practice should also be applied in preparation for future changes (within reason).
It's so much harder to separate a monolithic project than it is to work with separate projects from the start, which means you should generally err towards separating your projects before you start actually needing them to be separated.

1
  • 1
    Well, I'm always amazed by the strength of this community. I really thanks you for the time and the effort you've put to give such a detailed and clear answer.
    – MaxouMask
    Jun 17, 2020 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.