Friday, January 23, 2009

A simple plug-in framework for .NET apps

If you want to add plug-in support to your application then you might start looking at Microsoft’s Managed Extensibility Framework or System.Addin. Whilst I have no experience of these frameworks, when I looked at them I decided they were just too complicated for my needs. Also I was targeting .NET 1.1 so couldn’t use either of them. All I wanted to be able to do was to write a class that implements a particular interface (for importing files from one of a number of external file formats), dump it in the application’s directory and for the application to recognise the assembly and add the supported file type to its list of available file types. I won’t bore you with the details of the interface, since it’s obviously specific to the application being developed, but here’s the code for loading the assemblies and creating instances of the available importers.

      // load all importers
      string applicationDirectory = System.IO.Path.GetDirectoryName(
        Assembly.GetExecutingAssembly().Location);
      DirectoryInfo info = new DirectoryInfo(applicationDirectory);
      FileInfo[] files = info.GetFiles();
      List<Type> types = new List<Type>();
      for (int i = 0; i < files.Length; i++)
      {
        // load assemblies and see what is in there
        if (files[i].Extension.ToLower() == ".dll")
        {
          Assembly thisAssembly = Assembly.LoadFrom(files[i].FullName);
          Type[] assemblyTypes = thisAssembly.GetTypes();
          for (int j = 0; j < assemblyTypes.Length; j++)
          {
            if (assemblyTypes[j].GetInterface("IImport") != null)
            {
              ConstructorInfo wfConstructor = assemblyTypes[j].GetConstructor(Type.EmptyTypes);
              object obj = wfConstructor.Invoke(null);
              IImport importer = (IImport)obj;

              importers.Add(importer);
            }
          }
        }
      }

This worked well for me. I’m sure it wouldn’t work in all scenarios and MEF/System.Addin may be more appropriate to more complex scenarios (if you are worried about versioning or running your add-in in a sandbox for instance) but it’s a quick and dirty method for implementing plug-ins.

No comments: