I do not follow SOLID strictly in general, but I do try making sure to separate responsibilities of my classes.

I was developing a small app with a Windows service powered by Topshelf and realized that I don't quite understand what should Program class do. Obviously I could probably shove most code into Main, but what is the reasonable amount of responsibilities that this class should have?

My options:

  1. Program is just a housing for Main, which is just an entry-point for the app, and the rest of the code should be moved to a separate class.

  2. Main should only be a composition root of the application, with a separate class handling general workflow (like graceful shutdowns on exceptions) and calls to business logic.

  3. Another static method in Program should be handling the composition and calls to application class.

  4. Program is the application workflow class and its nonstatic methods call business logic, while Main is an entry point.

  • Any of those 4 options could be the right one for you. The prerequisite to being able to follow SRP is to understand what your objectives are in the first place. i.e. what is it that you're trying to achieve? The SOLID principles, and especially SRP are intended to help steer you towards a design which meets the KISS and DRY principles, and also makes code easy to test. Start out by thinking about how you will write your tests and then choose the option which lets you have gets you as close to KISS/DRY as possible. The right choice of those 4 is the one which minimises complexity. – Ben Cottrell Oct 5 '18 at 17:26

The approach I take is to view Program.Main as untestable without running the app. Therefore, it (and the rest of Program) should only have responsibility for setting up the runtime composition and kicking things off. Everything else should exist in other classes so that they can be tested, individually or in other, non-runtime, compositions as needed.

If the composition is simple, put it in Main, otherwise have Main call a private composition method (or even another class if really complex) to perform that composition.

So I'd opt for a mixture of options 2 and 3, depending on size. Option 1 is also worth considering when composition occurs in another class. Just don't do option 4 in my view.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy