I am increasingly aware that my code in any single file can often span hundreds of lines quite easily and although I know the implementation might be sound, it still feels messy
Separate your code into responsibilities. For each responsibility, define a single type. That is, follow the Single Responsibility Principal. Doing so will result in smaller units of code, each of which performs a very specific function. Not only does this result in smaller files, but also in better design and maintainability.