views:

92

answers:

3

I want to create a class, that is flexible so I can switch implementations.

Problem: Store files/documents
Options: either store locally on the server filesystem, database or etc.

Can someone help with a skeleton structure of the class, and how I would call it?

I am not using an IoC, and don't really want to just yet. I just want the flexibility where I would make maybe 1 code change in the factory to call another implementation.

+4  A: 

interface it. Whereever you need to store files, just allow an IFileStorer. If you need a new way to store it, just add another IFileStorer type.

interface IFileStorer
{
    void Store(string file, byte[] data);
}

class LocalStorer : IFileStorer
{
   void Store (string id, byte[] data)
   {
      //code to store locally
   }
}


class DBStorer : IFileStorer
{
   void Store (string id, byte[] data)
   {
      //code to store in db
   }
}

class AnywhereStorer : IFileStorer
{
   void Store (string id, byte[] data)
   {
      //code to store in anywhere
   }
}
santosc
+4  A: 

Use an interface.

interface IStorage
{
    void Save(string filename);
}

Then create your various implementations:

class LocalStorage : IStorage
{
    void Save(string filename)
    {
        -implementation code-
    }
}

And then, in your consumer classes

IStorage storage = new LocalStorage();

// uses local storage
storage.Save();

storage = new DatabaseStorage();

// now use database storage
storage.Save();
DanDan
+1. The LocalStorage class might have a string rootDirectory constructor parameter, while the DatabaseStorage class might require a repository (or other data access class), etc..
Jeff Sternal
+2  A: 

Just to add a little what others have posted, if you want to really just make one change, consider a static factory:

public interface IFileStorage
{
   void Store(); //parameters if needed
}

public class FileStorage : IFileStorage
{
   public void Store(){}
}

public class DatabaseStorage : IFileStorage
{
   public void Store(){}
}

Then, have an enum that you will map to the concrete classes:

public enum FileStorageTypes
{
   Database,
   FileSystem
}

and finally the factory:

public static class StorageFactory
{
   public static IFileStorage GetStorage(FileStorageTypes types)
   {
      switch(types)
      {
         case FileStorageTypes.Database: return new DatabaseStorage();
         case FileStorageTypes.FileSystem: return new FileStorage();
      }
   }
}

Then, if you have somewhere in your code that you need to do some storage work:

public void DoStorage(IFileStorage storage)
{
   storage.Store();
}

You can just call this method:

DoStorage(StorageFactory.GetStorage(FileStorageTypes.Database));

and easily swap it out if needed.

BFree
+1 could use the config file to grab the desired one, and in the future use an IOC.
CSharpAtl