In my last post in this IFileSystem series, I described the problem I'm working on of removing a dependency on the System.IO Windows file system in my ASP.NET application. A bit of research on this subject revealed some help on making file uploads testable by ScottHa, but his technique still makes use of the SaveAs() method and ultimately ties the solution to the server file system. A similar post on creating Unit Test Friendly File Uploads was more helpful, in that it provided some helper methods for saving files from HttpPostFile without using its built-in SaveAs() method.
Since my ultimate goal is to be able to swap between Amazon S3 and Windows file systems (and likely Azure as well), I decided to create a spike solution that allows me to accomplish both tasks using the same API. To this end, I created a simple ASP.NET web form like so:
Now I know what my signature needs to be for IFileSystem's WriteBinaryFile() method, and I have implementations that work for both S3 and Windows. I also know the implementation-specific properties/configuration each implementation will need, specifically the upload folder for System.IO and the S3 keys and bucket name for S3.
Note that I'm making use of the Affirma ThreeSharp Amazon S3 library in the above code, available for free on CodePlex.
The next step is to throw away my spike solution and go back and TDD my IFileSystem to provide direct support for WriteBinaryFile. Then I need to get my ugly GetImageOrFlashData() method under test, apply some Dependency Injection (via the Strategy pattern) to it, and hopefully I'll then be able to flip a switch in my application and have the uploaded file go directly to Amazon S3 (without ever hitting my server's disk) or to my server's disk.
(Note that later we may decide it's wiser to always upload to server disk, and then persist to S3/Azure/Cloud storage using a separate worker process. For now that's a premature optimization and we're just going to work on getting the simple, synchronous case to work first).