0 votes
by (210 points)
edited

Both the Sftp and Ftp classes implement the IFtp interface. They both also have a method .Connect(string). I'm wondering why this wasn't put on the interface. I'm trying to write a generic class that uses the IFtp interface, and it isn't working well because of that missing method.

3 Answers

0 votes
by (58.9k points)
edited
 
Best answer

We have not implemented the Connect method in the IFtp interface because of the different nature of SFTP and FTP(/SSL) protocols. I.e. there is no SSL mode in SFTP and there is the rub. So the question would be what SSL mode would be used then? And if you choose one of the variants (implicit/explicit/no SSL mode for FTP), the others would fail.

So the solution would not be universally suitable.

However we are planning to create a class which would be universal for both SFTP and FTP protocols. This would implement the Connect method. We will post here, once it is ready.

Update: The universal SFTP/FTP client class has been released as part of Rebex File Transfer Pack 2014 R2. It implements IFtp and adds Connect and Login methods.


Meanwhile, could you call the Connect and Login methods just after instantiating the Ftp or Sftp object as in the code below?

public IFtp GetIFtpInstance()
{
    // connect to a server according to its type
    switch (serverType)
    {
        case "ftp":
            // create an instance of Ftp object
            var ftp = new Ftp();

            // connect and authenticate to an FTP server
            ftp.Connect(hostname);
            ftp.Login(username, password);

            // return Ftp instance
            return ftp;

        case "sftp":
            // create an instance of Sftp object
            var sftp = new Sftp();

            // connect and authenticate to an SFTP server
            sftp.Connect(hostname);
            sftp.Login(username, password);

            // return Sftp instance
            return sftp;

        default:
            throw new Exception("Invalid server type.");
    }
}
+1 vote
by (210 points)
edited

Thanks for the quick response. I'd also like to say I'm pretty new to all of this, so there are probably some nuances that I'm not familiar with yet.

Having said that, in your example, you call Connect(string) after you instantiated each of the types. That leads me to believe that it should be able to be added to the interface. That would also help with unit testing/mocking.

After I asked the question, I continued with what I was doing and pretty much came up with the same thing you did. I did it in a more OO way, but basically is the same. I created a base class with an abstract GetInstance() method. Then subclasses that override and return the correct instance.

0 votes
by (148k points)
edited

Yes, it would be possible to add Connect(string) to the interface, we just thought it would not be very useful - it would only work with the protocol the object actually implementes. We will eventually add it, however, together with a new FileTransferClient object that wraps both Ftp and Sftp and supports both protocols.

However, in the meantime, what about declaring Connect(string) as an extension method?

public static class FileTransferExtensions
{
    public static void Connect(this IFtp client, string serverName)
    {
        Ftp ftp = client as Ftp;
        if (ftp != null)
        {
            ftp.Connect(serverName);
            return;
        }

        Sftp sftp = client as Sftp;
        if (sftp != null)
        {
            sftp.Connect(serverName);
            return;
        }

        throw new NotSupportedException("Unsupported object.");
    }
}
by (210 points)
edited

That is certainly an option. The thing I did with the virtual methods is working great for me. Thanks again for all your help.

...