While writing my CruiseCli project, I needed to do some data storage, and so used my standard method of filesystem access, the
IFileSystem. This is an interface and implementation which I tend to copy from project to project, and use as is. The interface looks like the following:
And the standard implementation looks like the following:
This (I think) is a very good solution to file system access as I can easily mock the interface and add expectations and stub values to it for testing.
However, on the CruiseCli project, I realised I didn't need most of what the interface provided, so I chopped all the bits off I didn't want, and added a property for a base directory I was using all the time:
Which was better than the original, as I have a lot less methods to worry about, and thus it is more specific to my use case.
But I got thinking later in the project; "what are my use cases?", "what do I actually want to do with the filesystem?" The answer to this was simple: Read a config file, and write to the same config file. Nothing else.
So why not make the interface even more specific in this case:
Even simpler, and I now have the benefit of not caring what the filepaths are outside of the implementing class.
This means that in my integration tests, I can write an in-memory
IConfiguration with far less hassle, and not need to worry about fun things like character encoding and case sensitivity on filepaths!
In a more complicated system, I would probably keep this new
IConfiguration interface for accesing the config file, and make the concrete version depend on the more general
For a small system this would probably be overkill, but for a much larger project, this could help provide a better seperation of responsibilities.