1

I am using an Export Module, now I want to extend it for different connections. I have a database which contains products Its Description, Review, Images etc. I use the serialize function to save it as XML file. After saving it as XML, in admin pannel I have possibility to select how this XML file will be exported.

for example throught ftp, http, local, webservice, email etc. user has the possibility to select one or more connections to export the files.

Each connection like ftp, http has it own settings in Database e.g ftp domain, username, password.

what will be the best way to write these connection classes (by implementing Interface or using Abstract class or some Manager)

and how to pass them to the export component as one exoprt may have on to many connections.

3

You can use something along the lines of the Factory Pattern.

A sample of it for your situation would be along the lines of

public interface IExporter
{
    void ExportXmlFile(string pathToFile);
}
public abstract class Exporter : IExporter
{
    public Exporter() { }

    public virtual void ExportXmlFile(string pathToFile)
    {

    }
}

public class ExportertFactory
{
    public static IExporter GetExporter(ExportType type)
    {
        switch (type)
        {
            case ExportType.Ftp:
                return new FtpExporter();
            case ExportType.Http:
                return new HttpExporter();
            case ExportType.Xml:
                return new XmlExporter();
            default:
                throw new Exception("Unknonw ExportType");
        }
    }
}
public enum ExportType
{
    Xml = 1,
    Ftp = 2,
    Http = 3
}

public class FtpExporter : Exporter
{
    public FtpExporter()
        : base()
    {
        //Connect to database to get FTP Settings
    }

    public override void ExportXmlFile(string pathToFile)
    {
        //Export File via FTP
    }

}
public class HttpExporter : Exporter
{
    public HttpExporter()
        : base()
    {
        //Connect to database to get Http Settings
    }

    public override void ExportXmlFile(string pathToFile)
    {
        //Export File via Http
    }
}

public class XmlExporter : Exporter
{
    public XmlExporter()
        : base()
    {
        //Connect to database to get Xml Settings
    }

    public override void ExportXmlFile(string pathToFile)
    {
        //Export File via Xml
    }
}

public class Client
{
    public Client()
    {

    }
    public void ExportFile()
    {
        IExporter exportMethod = ExportertFactory.GetExporter(ExportType.Ftp);
        exportMethod.ExportXmlFile("FilePath");
    }
}

Depending on what method the user clicks, or for each one you can create the necessary

IExporter exportMethod = ExportertFactory.GetExporter(ExportType.Ftp);
exportMethod.ExportXmlFile("FilePath");

exportMethod = ExportertFactory.GetExporter(ExportType.Http);
exportMethod.ExportXmlFile("FilePath");

lines for each one.

The abstract class Exporter is optional. You may chose to put some common functionality there for each export type. If you chose not to use it, just set each concrete implementation to use the interface, rather than the abstract class

  • There are some smells in this approach. It's not good to have 1:1 relation between some enumeration fields and classes. It's event worse as you need to 1) add class 2) add enum field 3) change switch statement all the time when you extending. And it's not so good to have dependencies on all the concrete classes in the switch statement. It should be composition root to know all about them only. – Dmitry Nogin Apr 11 '14 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.