Overview

The Source Code has a sample application in the MutableTranslator project that fully exercises the library and all the plugins. This page contains the following sections:

Available Translation Services

Microsoft Translator (Azure) - Developer Homepage: http://msdn.microsoft.com/en-us/library/dd576287.aspx

This is a paid service. For each application domain (this could be multiple applications owned by the same company), you need to go out to https://datamarket.azure.com/developer/applications/ and register the application and setup payment options. Once registered, you will be provided a Client ID (readable app name defined by you) and Client secret (long random characters). These two strings need to be passed into the AuthenticateAsync method in that order.

Microsoft Terminology Service - Developer Homepage: http://www.microsoft.com/Language/en-US/Microsoft-Terminology-API.aspx

This is a free service with no apparent limits, though it is not very fast and is very specific to translating standard messages found in Microsoft products. This is really good for common dialogs and strings you would expect to find in the operating system or productivity tools.

Glosbe Online Dictionary - Developer Homepage: http://glosbe.com/a-api

Glosbe is a free service, but has some limitations. Firstly, Glosbe is a word translator. It is not really a phrase translator. Secondly, there is a vaguely defined limit on calls. Their website says, "There is a limit of call that may be done from one IP in fixed period of time, to prevent from abuse." Do not pass any parameters into the AuthenticateAsync method.

Google Translate API - Developer Homepage: https://developers.google.com/translate/

This is a paid service tied to the paying entity. To register go to https://cloud.google.com/products/translate-api/ and setup payment options. Once registered, you will get an API key (long random characters). This string needs to be passed into the AuthenticateAsync method.

Yandex - Developer Homepage: http://api.yandex.com/translate/doc/dg/concepts/api-overview.xml

Yandex is a free service, but has some usage limits: 10,000 calls per day or 1,000,000 characters per day. You need to register first at https://passport.yandex.ru/passport?mode=register. I recommend using Chrome as Internet Explorer has some problems with the Russian. Once registered, you can request an API key (long random characters). This string needs to be passed into the AuthenticateAsync method.

Basic code for getting a translation

This self-documented code shows how to use a single service plugin for connecting and then translating a single piece of text.

public static async System.Threading.Tasks.Task<string> Translate()
{
   // You can replace the constructed object with any of the available plugins.
   // Here we start with the Google service.
   ITranslatorService CurrentService = new GoogleTranslator.GoogleTranslator();
   if ((CurrentService.ServiceCapabilities & TranslatorServiceCapabilities.RequiresAuthentication) ==
      TranslatorServiceCapabilities.RequiresAuthentication)
   {
      string[] authParams = CurrentService.AuthenticationParameterDetail;
      if (authParams != null && authParams.Length > 0)
      {
         // Each plugin requires different authentication parameters. The 'authParams'
         // value has the names of the parameters required.

         // Google requires an APIKey which can be retrieved at https://cloud.google.com.
         if (CurrentService.ServiceName == "Google Translator" && authParams.Length == 1)
            authParams[0] = "ABVDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

         // Azure requires an ClientID and a ClientSecret which can be retrieved at
         // https://datamarket.azure.com/developer/applications/.
         if (CurrentService.ServiceName == "Microsoft Translator" && authParams.Length == 2)
         {
            authParams[0] = "MyAppID";
            authParams[1] = "ABVDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
         }

         // Yandex requires an APIKey which can be retrieved at http://api.yandex.com/translate/.
         if (CurrentService.ServiceName == "Yandex Translator" && authParams.Length == 1)
            authParams[0] = "ABVDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

         if (!await CurrentService.AuthenticateAsync(authParams))
            throw new UnauthorizedAccessException();
      }
   }

   if ((CurrentService.ServiceCapabilities & TranslatorServiceCapabilities.TranslatesPhrases) ==
      TranslatorServiceCapabilities.TranslatesPhrases)
   {
      var res = await CurrentService.TranslateAsync("en-us", "fr-fr", "Press the Enter key");
      return res;
   }

   return null;
}

Code for managing multiple plugins

This code provides a generic class library for managing plugin assemblies found in a single directory. For this project, instantiating this class as new PluginManager<ITranslatorService>("Plugins") will look in the Plugins folder of the folder in which the program resides and make all provided services available.

using System.Reflection;

/// <summary>
/// Generic class which will search all assemblies in a directory for a defined interface and maintain a list of instances.
/// </summary>
/// <typeparam name="T">Interface to discover in assemblies.</typeparam>
public class PluginManager<T> : IDisposable where T : class
{
   /// <summary>
   /// Initializes a new instance of the <see cref="PluginManager{T}"/> class.
   /// </summary>
   /// <param name="path">The path to the assemblies.</param>
   public PluginManager(string path)
   {
      Plugins = new List<T>();
      LoadPlugins(path);
   }

   /// <summary>
   /// Gets a collection of instantiated Plugins.
   /// </summary>
   /// <value>
   /// The plugins.
   /// </value>
   public ICollection<T> Plugins { get; private set; }

   /// <summary>
   /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
   /// </summary>
   public void Dispose()
   {
      Plugins.Clear();
   }

   private void LoadPlugins(string path)
   {
      if (Directory.Exists(path))
      {
         Plugins.Clear();
         Type pluginType = typeof(T);
         foreach (string dllFile in Directory.GetFiles(path, "*.dll"))
         {
            try
            {
               AssemblyName an = AssemblyName.GetAssemblyName(dllFile);
               Assembly assembly = Assembly.Load(an);
               if (assembly != null)
               {
                  foreach (Type type in assembly.GetTypes())
                  {
                     if (type.IsClass && type.IsPublic && !type.IsAbstract)
                     {
                        if (type.GetInterface(pluginType.FullName) != null)
                        {
                           try
                           {
                              Plugins.Add((T)Activator.CreateInstance(type));
                           }
                           catch { }
                        }
                     }
                  }
               }
            }
            catch { }
         }
      }
   }
}

Last edited Jul 9, 2014 at 5:15 PM by dahall, version 3