2

Perhaps this is too broad a question, but I still want to hear what are the best practices and what is considered 'correct'. I did not find a similar topic, probably due to how generic it is and thus hard to search.

This all began when we took a windows service project and added another service to it. Previously, the main method was what we considered the Composition Root, and our IoC container registration code, app.config reading and similar was in the main method in one form or another. After assembling required dependencies there we created the service by calling Resolve on the container and running it.

When we created another class inheriting from ServiceBase we noticed that it did not make sense to have the main as the composition root anymore, because the multiple services are potentially completely different and thus require different initialization code.

The only enlightening post I found on the mather was this one from Mark Seemann, where he states that the OnStart would be the aggregate root (in that particular case).

In general, what is the best approach to take when choosing and appropriate composition root? Should I consider this windows service scenario an outlier and just code differently for it while leaving the main method as other project types composition roots, or is there a more general approach that would be valid in all contexts?

Perhaps the fact that the services require very different setups is an indicator that they should be separated in multiple standalone projects, where the main would be again used as the composition root?

We generally use .Net but this probably applies to many other programming languages as well.

Community
  • 1
  • 1
julealgon
  • 7,072
  • 3
  • 32
  • 77

1 Answers1

0

It's best to think of the Main() method as a mere hook that's required by the OS - and that should be its only responsibility. There should be as few code in it as possible, only the bare minimum that is required to start the actual application - it should not be part of any conceptual considerations at all.

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34
  • What is your suggestion then for where to put initialization code? For instance container setup, log configuration. Could create a small sample for that perhaps? – julealgon Jan 09 '14 at 13:33
  • Depends. In your case I would write a method (called `Init()` or the like) and call this method from 'Main()'. Then I would have a method `Run()` (which is essentially an infinite loop that waits for something to happen), finally eventually a method 'CleanUp()'. Main then would read ´{ Init(); Run(); CleanUp(); }´. – Thomas Weller Jan 09 '14 at 13:39
  • Notice that the case I described has two independent services. If I do what you suggest I would be coupling them in single initialization methods and I can't have any precedence between them: imagine that I have two services in the same process, and the second depends on the first to run. If I use the program class as the composition root like you suggest I wouldn't be able to initialize the second service properly, because the first wouldn't be running already. – julealgon Jan 09 '14 at 13:44
  • Forget about that 'composition root' thing - it won't help you much and it's also not common to talk about entry points this way. Regarding the two services, I think I'll simply double the `Init()` methods - one for each service. – Thomas Weller Jan 09 '14 at 13:54