tags:

views:

96

answers:

3

My application stores files, and you have the option of storing the files on your own server or using S3.

I defined an interface:

interface FileStorage {

}

Then I have 2 implementations, S3FileStorage and LocalFileStorage.

In the control panel, the administrator chooses which FileStorage method they want, and this value is stored in a SiteConfiguration object.

Since the FileStorage setting can be changed while the application is already running, would you still use spring's DI to do this?

Or would you just do this in your code:

FileStorage fs = null;

switch(siteConfig.FileStorageMethod)
    case FileStorageMethod.S3:
        fs = new S3FileStorage();

    case FileStorageMethod.Local:
        fs = new LocalFileStorage();

Which one makes more sense?

I believe you can use DI with spring during runtime, but I haven't read about it much at this point.

+2  A: 

I would still use Dependency Injection here. If it can be changed at runtime, you should inject it using setter injection, rather than constructor injection. The benefit of using any dependency injection is that you can easily add new implementations of the interface without changing the actual code.

Jeff Storey
+3  A: 

I would inject a factory, and let clients request the actual services from it at runtime. This will decouple your clients from the actual factory implementation, so you can have several factory implementations as well, for example, for testing.

You can also use some kind of a proxy object with several strategies behind it instead of the factory, but it can cause problems, if sequence of calls (like open, write, close for file storage) from one client cannot be served by different implementations.

axtavt
Agreed. While I suggested using DI below, injecting a factory works well too.
Jeff Storey
+1  A: 

DI without question. Or would you prefer to enhance your factory code when you create/update/delete an implementation? IMO, If you're programming to an interface, then you shouldn't bootstrap your implementations, however many layers deep it actually occurs.

Also, DI isn't synonymous to Spring, et al. It's as simple as containing a constructor with the abstracted interface as an argument, i.e. public FileApp(FileStorage fs) { }.

FYI, another possibility is a proxy.

Droo