Developer Tutorial
This developer tutorial will guide you through the steps of:
1. Using the client API to build user interfaces that benefit from the transfer controller and its
plug-in architecture;
2. Developing new plug-ins for the client API and Memba Velodoc Outlook Add-In.
We highly recommend you read the “Design and Architecture” document first.
The “Installation Guide” also describes how to install the source code in a development
environment.
Client API
The client API is a good fit to pilot file transfers from a rich client user interface. We use it in the
Memba Velodoc Outlook Add-In. It is not a good fit to transfer files from a web interface. In this
case, consider Velodoc XP Edition and its Ajax components.
IMPORTANT: The client API has not been designed to work as a server API. It is the client component
of a client-server architecture.
The client API contains 4 main object types: TransferAgent, ITransferAccount, ITransferPackage and
ITransferFIle. Although they are split across two assemblies, Memba.Transfer.ClientAPI.dll and
Memba.Transfer.dll, which you need to reference in your projects...
1
Copyright © 2007-2008 Memba SA. All rights reserved.
... they are all part of the Memba.Transfer.ClientAPI namespace and you only need one directive for
resolving class names in your code:
using Memba.Transfer.ClientAPI;
These 4 classes and interfaces have the following responsibilities:

A TransferFile object (implementing ITransferFile) represents a file to be transferred; It is
the equivalent of an email attachment;
A TransferPackage object (implementing ITransferPackage) represents a message to be sent
which possibly contains several ITransferFile objects ;
A TransferAccount object (implementing ITransferAccount) represents an account to access
a file transfer server platform, including Velodoc Enterprise Edition, Velodoc XP Edition, FTP
Servers, Microsoft BITS Servers, UNC File Shares and Amazon S3.
The TransferAgent object has two functions:
o It is a static factory which you will use to create TransferFile, TransferPackage and
TransferAccount objects;
o It implements the 3 main methods of the API, which are Send, Upload and
Download.



This is described in the “Architecture and Design” document.
Uploading a file
Depending on the remote server and the plug-in, uploading a file would generally require
credentials. In this example, we have chosen to demonstrate how to get a named account from the
persistence store. It is assumed that you have created this account from the account settings dialog
box.
//Create transfer file
string sLocalFile = "C:\\img1.jpg";
ITransferFile objTransferFile = TransferAgent.CreateFile(sLocalFile);
//Get upload account
ITransferAccount objTransferAccount = TransferAgent.GetAccount("My Account Name");
//Upload
TransferAgent objTransferAgent = new TransferAgent(objTransferAccount);
objTransferAgent.Upload(ref objTransferFile);
//Confirm
MessageBox.Show("File uploaded to " + objTransferFile.RemoteFile.AbsoluteUri);
You can find a sample implementation of this code in the TestAPI project and in the unit tests.
Downloading a file
Downloading a file only requires that you now the Uri of the remote file and that you know which
plug-in (protocol) to use to download the file. You do not even need an account saved in registry; i.e.
the account can be created on the fly, especially with anonymous downloads.
2
Copyright © 2007-2008 Memba SA. All rights reserved.
//Create transfer file
Uri objRemoteFile = new
Uri(("ftp://10.0.0.12/Download/fd033773749946a59926ba18bb8ced23/img1.jpg");
string sFileName = objRemoteFile.Segments[objRemoteFile.Segments.Length - 1];
string sLocalFile = System.IO.Path.Combine("C:\\", sFileName);
ITransferFile objTransferFile = TransferAgent.CreateFile(sLocalFile,objRemoteFile);
//Create download account
ITransferAccount objTransferAccount =
TransferAgent.CreateAccount("temp", FTPPlugIn.PLUGINNAME);
//Download
TransferAgent objTransferAgent = new TransferAgent(objTransferAccount);
objTransferAgent.Download(ref objTransferFile);
//Confirm
MessageBox.Show("File downloaded to " + objTransferFile.LocalFile);
You can find a sample implementation of this code in the TestAPI project and in the unit tests.
Sending a package
Depending on the remote server and the plug-in, sending a package would generally require
credentials. You can build your account on the fly, like in the following example, but in this case we
get a named account from the persistence store. You should have created this account from the
account settings dialog box.
//Create package
ITransferPackage objTransferPackage = TransferAgent.CreatePackage(
"New Package",
//Name
"joe.bloggs@acme.com",
//From
"john.smith@world.com",
//To
"paul.smith@world.com",
//Cc
"peter.smith@world.com",
//Bcc
"Hello World!",
//Subject
"Please find some files attached"); //Body
objTransferPackage.IsCompressed = true;
objTransferPackage.EncryptionPassword = "my secret";
//Add ‘attachments’
ITransferFile objTransferFile = TransferAgent.CreateFile("C:\\img1.jpg");
objTransferPackage.AddFile(objTransferFile);
ITransferFile objTransferFile = TransferAgent.CreateFile("C:\\img2.jpg");
objTransferPackage.AddFile(objTransferFile);
//Create sender account
ITransferAccount objTransferAccount = TransferAgent.GetAccount("My Account Name");
//Send
TransferAgent objTransferAgent = new TransferAgent(objTransferAccount);
objTransferAgent.Send(ref objTransferPackage);
You can find a sample implementation of this code in the TestAPI project and in the unit tests.
Note that you still have to send the email with the links to download the files using an API like
System.Net.Mail unless the remote server emits the notification based on the XML manifest
received. The manifest is an XML representation of the transfer which can be transferred by the
plug-in for the remote server to create records and/or send email notifications.
3
Copyright © 2007-2008 Memba SA. All rights reserved.
Testing/debugging with the Mockup Service plug-in
If you develop a client interface with the client API, it is easier to test with the Mockup Service plugin implemented in Memba.Transfer.PlugIns.DummyPlugIn.cs (only available in debug mode). The
mockup service plug-in simulates a transfer but does not transfer anything. Accordingly it does not
require any specific account settings.
Developing transfer plug-ins
Memba Velodoc transfer plug-ins constitute an abstraction layer which handles the specificities of
each file transfer server platform: Velodoc servers, FTP servers, Microsoft BITS servers, Amazon S3
and others.
A transfer plug-in for Memba Velodoc Outlook Add-In is a class which inherits from
Memba.Transfer.PlugIns.TransferPlugInBase (in assembly Memba.Transfer.dll):
public sealed class FTPPlugIn : Memba.Transfer.PlugIns.TransferPlugInBase
TransferPlugInBase is an abstract class which implements the ITransferPlugIn interface which has the
following Members divided into:





Plug-in properties
Plug-in capabilities
Account settings
Remote file information
Transfer commands
Plug-in properties
Plug-in properties describe the parameters required to run the plug-in:
string Name { get; }
string[] SettingsParams { get; }
string[] EncryptedParams { get; }
Gets the plug-in name (read-only)
Gets an array of settings parameter names.
For example, the FTP plug-in returns
{ “host”, “passivemode”, “uploadvdir”,
“username”, “password”, “downloadvdir”,
“proxyconfig”, “proxyuri”, “proxyport” }
Gets an array of settings parameter names that
need to be encrypted in the persistence store.
For example, the FTP plug-in return {“password”}
The persistence store is the registry. When saving an account created for the FTP plug-in, the
following registry names and values will be created under the account key:
4
Copyright © 2007-2008 Memba SA. All rights reserved.
There is one specific parameter which is “email”, which when added to SettingsParams will override
the sender’s email in the transfer package. This is important in the Outlook plug-in because you may
have several Outlook accounts, but only one account on the file transfer server which uses the email
as the user identifier. This allows you to send packages from any of your Outlook accounts using
always the same account on the file transfer server platform.
Plug-in capabilities
Plug-in capabilities describe what the plug-in can and cannot do. All these capabilities have a default
implementation in TransferPlugInBase and you only need to override the ones which change.
bool CanUpload { get; }
bool CanDownload { get; }
bool IsTransferDelegated { get; }
bool CanProcessManifest { get; }
5
Checks whether the current plug-in can upload files.
The default implementation in the
TransferPlugInBase abstract class returns true.
Checks whether the current plug-in can download
files.
The default implementation in the
TransferPlugInBase abstract class returns true.
Checks whether the plug-in executes the transfer or
delegates the transfer to another process, for
example the BITS windows service. This is essentially
used not to pause/resume transfers when exiting the
controller since the transfers do not execute in the
controller process.
The default implementation in the
TransferPlugInBase abstract class returns false.
Checks whether the plug-in (or more exactly the
remote service) can process manifests. A manifest is
an XML blueprint of the transfer which can be passed
to the remote service to create database records or
else. This is only used with the Velodoc server
platforms.
The default implementation in the
TransferPlugInBase abstract class returns false.
Copyright © 2007-2008 Memba SA. All rights reserved.
string HashAlgorithmName { get; }
bool
UseRegisteredProtocolHandlerForDo
wnloads { get; }
Gets the hash algorithm used for hashing transferred
files (read-only). This name should follow the
conventions used by
System.Security.Cryptography.CryptoConfig.
CreateFromName.
The default implementation in the
TransferPlugInBase abstract class returns “SHA1”.
Checks whether downloads should be handled by a
registered protocol handler. For example the browser
is the default protocol handler for http: and ftp: (see
http://msdn.microsoft.com/enus/library/aa767914(VS.85).aspx). In this case, the
controller would launch the browser to execute the
download.
This capability only applies if CanDownload returns
false.
The default implementation in the
TransferPlugInBase abstract class returns false.
Account settings
The plug-in members related to account settings are the following and need to be implemented in
every plug-in.
bool
AreSettingsOK(NameValueCollection
plugInSettings, out string message);
object GetSettingsControl();
Checks plug-in settings and returns an error
message if plug-in settings are invalid (returning
false).
Returns the user control used to display/modify
settings in the account settings dialog. The
object returned must inherit from UserControl
and implement the ITransferPlugInSettings
interface..
The method skeletons are created by right-clicking TransferPlugInBase in the class declaration
statement and selecting contextual menu “Implement Abstract Class”:
6
Copyright © 2007-2008 Memba SA. All rights reserved.
Remote file information
The following members represent information about a remote file hosted on a file transfer server
platform. GetRemoteFIle and GetRemoteSize need to be implemented by your plug-in.
Uri GetRemoteFile(ITransferInfo
transferInfo, string localFile,
Nullable<Guid> itemId, bool
isManifest);
long GetRemoteSize(ITransferInfo
transferInfo, Uri remoteFile);
string
GetRemoteContentType(ITransferInfo
transferInfo, Uri remoteFile);
Computes the remote file uri used for downloads
(this method is only used in the context of
uploads). This should return the uri required to
download the file which may be different from
the uri used to upload the file.
Gets the size of a remote file (this method is only
used in the context of downloads). The size is
returned as a number of bytes.
Gets the content type of a remote file (this
method is only used in the context of
downloads). There is a default implementation in
TransferPlugInBase which returns the mime type
recorded in the registry for the file extension, so
you generally do not have to implement this
member.
Transfer commands
The following members execute the transfer commands: start, pause, resume and cancel. They have
default implementations in TransferPlugInBase which you do not need to change.
void Start(ITransferInfo
transferInfo);
7
Starts a new transfer including several files. The
default implementation in TransferPlugInBase
looks at transferInfo.Direction and if it is an
upload, it passes a call to the Upload override
(see next table below) to the thread pool and if it
Copyright © 2007-2008 Memba SA. All rights reserved.
void Pause(ITransferInfo
transferInfo);
void Resume(ITransferInfo
transferInfo);
void Cancel(ITransferInfo
transferInfo);
is a download, it passes a call to the Download
override (see below too) to the thread pool. So
you only really have to implement upload and
download below.
Pauses a transfer. The default implementation in
TransferPluginBase only changes the status of
the TransferInfo to PauseRequested. Your code
in the upload and download overrides should
periodically query this status to pause the
transfer.
Resumes a transfer. The default implementation
in TransferPluginBase only restarts the transfer
by passing an upload or a download to the
thread pool. So your upload and download
overrides need to be re-entrant and check for
the completed status of a TransferItem before
uploading or downloading it.
Cancels a transfer. The default implementation
in TransferPluginBase only changes the status of
the TransferInfo to Cancelled. Your code in the
upload and download overrides should
periodically query this status to cancel the
transfer.
You only need to override these two virtual members of TransferPlugInBase:
protected override void
Executes the upload defined in a TransferInfo
Upload(object state)
object.
protected override void
Executes the download defined in a TransferInfo
Download(object state)
object.
These two methods are obviously the most important part of your plug-in. We have completed 6
implementations which are open-source and which constitute sample code to learn from:
 The FTP plug-in,
 The UNC file share plug-in,
 The BITS plug-in,
 The Amazon S3 plug-in,
 The Velodoc XP plug-in (based on WCF web services),
 The Velodoc Enterprise Edition plug-in (based on BITS too).
Building and testing your plug-in
You may find easier to test your plug-in with the TestAPI winforms application than with the Outlook
add-in and I strongly encourage you to build unit tests for your plug-in using the existing unit tests as
a blueprint.
Installing your plug-in
In order for your plug-in to run flawlessly, it is necessary to sign the assembly with a strong name
and to add a membership condition to the Memba.Transfer.1 code group:
8
Copyright © 2007-2008 Memba SA. All rights reserved.
This can easily be done by executing Memba.Transfer.AddIns.AddInInstaller with the InstallUtil
installer tool.
Building the Visual Studio solution
Building the Memba Velodoc Outlook Add-In is a standard Visual Studio 2008 build process. There
are a few known issues:
Known issue 1
If you are using source control, the Release version will not build if you do not check out the
following two files from the setup project:


Memba.Transfer.AddIns.Outlook2007.dll.manifest
Memba.Transfer.AddIns.Outlook2007.vsto
9
Copyright © 2007-2008 Memba SA. All rights reserved.
Known issue 2
Apparently you cannot exclude permanently the following files from the setup project:










Microsoft.Office.Interop.Outlook.dll (v.11)
Microsoft.Office.Interop.Outlook.dll (v.12)
Microsoft.Office.Interop.SmartTag.dll (v.11)
Microsoft.Office.Interop. SmartTag.dll (v.12)
Microsoft.Office.Interop.Word.dll (v.11)
Microsoft.Office.Interop. Word.dll (v.12)
Microsoft.Vbe.Interop.dll (v.11)
Microsoft.Vbe.Interop.dll (v.12)
Office.dll (v.11)
Office.dll (v.12)
Each time you reload your solution, they get reloaded so you need to select them all as shown
below, right-click to display the contextual menu and select Exclude before you build your setup.
10
Copyright © 2007-2008 Memba SA. All rights reserved.
Known issue 3
Sometimes the setup you generate will fail to load properly in Outlook 2007 with the following error:
“File ... has a different computed hash than specified in the manifest”:
11
Copyright © 2007-2008 Memba SA. All rights reserved.
If this occurs, you need to:
1.
2.
3.
4.
Close Visual Studio;
Re-open the solution;
Execute the steps described in Known Issue 1 and Known Issue 2 above
Rebuild your setup
This works all the time for us. I hope this will work for you too.
12
Copyright © 2007-2008 Memba SA. All rights reserved.