Worker service recommended folder structure / namespaces

Hi there, I used to do a lot of procedural programming. Now, I have to build an OOP C# Worker service that processes files (Extract data, create JSON/XML or write data into a DB). I already know the basics of OOP and have built some smaller Java applications. Is there a recommended or best practice folder structure or pattern, like MVC, for a Worker service? For example, in Java, I had to build an abstract class and two child classes (in-memory and database) in order to write unit tests.
3 Replies
becquerel
becquerel3w ago
MVC and similar patterns are really most concerned about separating your business logic from your 'view', which isn't really present in a worker service. But the similarity is you still want a clear delineation between your 'pure' business code and the stuff which knows it's running in a worker service/console app For this reason I usually have the worker in one project and then all the platform-agnostic code in a separate project it references. For folder structure specifically, feature-based organisation is becoming more popular these days. So all your types related to (say) UserOrders would go in one folder, regardless of if they're models, services, repositories, etc. Your last line makes me think you are interested in making sure your code is testable, but that is a bit of a big topic separate to how you organise your code. Generally I find it more worthwhile to get integration tests set up that to try and abstract away my database for the sake of unit tests
jojomueller05
jojomueller05OP3w ago
Thank you for your answer. So if I've understood you correctly, it's a good practice to create a separat Porject where the classes live, structured by Entity (e.g. FileWriter/, Customer/, DB/, ...), and consume those classes in the Worker Service Project? Yes, I need to have testable code. Do you have any good resources on how to write testable code in C#? I'm interested in both unit and integration testing.
becquerel
becquerel3w ago
structured by Entity (e.g. FileWriter/, Customer/, DB/, ...),
no, structured by feature - that's an important distinction organise your code based on the categorisations real humans would care about, not programmers i.e. 'all the code for signing up new users goes into this folder', 'all the code for sending newsletter emails out goes into this folder' organising things based by if it's a filewriter or about the database goes against this the motivation for this is that code usually changes based on feature, and code that changes together should live together e.g. if you need to change your newsletter email feature, you don't want to have to search around five different 'layers' to find all the relevant code
good resources on how to write testable code in C#?
very big topic i would say the biggest things are - for unit tests, avoid non-determinism. if you use randomness, make it so you can seed it. don't use DateTime.Now - inject an ISystemClock instead. I/O is inherently non-deterministic, so either avoid doing I/O in your business code (best option) or mock it out (easier) - for integration tests, look into Testcontainers. it's far easier to just spin up a real database in a container than to try to make a fake database or mock it out - get your tests running in a continuous integration pipeline as a priority. otherwise you will forget to run them - generally, prefer to use dependency injection for your classes. it makes life a lot, lot easier. by that token, avoid using static methods or extension methods which do complex things, as you can't mock them out also, tests should measure the visible output of a system. they shouldn't try to peer inside a system to examine its internals i've seen tests which make assertions based on the log messages a class made - extremely useless and annoying lol

Did you find this page helpful?