I'm working on a C#/.NET Core project, and I'm looking for guidance on organizing interfaces, especially when it comes to using NSubstitute, Moq or other libraries for mocking, because there I need an interface. I've explored different approaches and would like to gather insights from the community.
Definitionsnamespace at the global level, i.e. a separate directory:
Example: The file
would e.g. have an interface living in
Advantage: Interfaces are neatly segregated, preventing clutter next to class files for those who don't require them.
Disadvantage: Accessing the interface from the class may require tools like ReSharper, which might be confusing without them.
- Advantage: Interfaces are easily discoverable when implementing a class in the IDE.
- Disadvantage: With many classes, managing numerous interface files can become cumbersome. There's also the risk of accidentally selecting the interface instead of the class.
Interfaces in the same file as the original class:
- Idea: Placing interfaces in the same file as their corresponding class.
- Advantage: Centralized and clutter-free project structure.
- Disadvantage: This approach might deviate from conventional C# coding styles.
I'm particularly interested in feedback related to using NSubstitute for mocking. Does the placement of interfaces affect your NSubstitute mocking strategy? Are there any specific pros or cons to consider in this context?
Reference: For more insights and historical discussions on interface organization in C#/.NET projects, you can refer to this related question on Software Engineering Stack Exchange. That one is more generic however, and this one is based on an a structure where you group by features, which I don't have in my project, it is more of a layered architecture, where one web request is processed and passed to the next layer to handle it etc.
Your insights and recommendations, especially in the context of NSubstitute, would be highly valuable. Thank you!
Alternative: You can actually use
ForPartsOf<> to also mock classes instead of interfaces, so I just don't need them. However, this has several disadvantages too IMHO:
- It needs virtual properties/methods and the classes must not be
- When you don't substitute/"configure" the methods explicitly, they run the real implementation, which is dangerous if you want to mock your dependencies in unit tests and accidentally execute totally different ones. This can lead to implementation problems.
Disclaimer/Full disclosure: This question has been improved by ChatGPT based on my own notes, but has been fully reviewed and improved by me. That was just a good writing help.