czwartek, 13 maja 2010

Jak zaimplementować mechanizm wtyczek (plugin'ów) w .NET (C#) [PL]

Promuj
Dziś będzie prosty artykulik o katalogach, plikach, assembly, typach, interfejsach itp... Czyli pokazane zostanie jak wykorzystać te wspomniane elementy, by zaimplementować prosty mechanizm wtyczek (plugin'ów) dla aplikacji.
Założenia:
  • Chcemy mieć aplikację, która wykorzystuje mechanizm wtyczek;
  • Wtyczka ma dostarczać pewien tekst (może robić co tylko zechcemy, ale przykład z założenia ma być prosty);
  • Wtyczka będzie plikiem DLL, który znajdować się będzie w tym samym katalogu co aplikacja korzystająca z wtyczek.
  • Każdy plik z wtyczką będzie się zaczynał od „Plugin”
Zastanówmy się teraz jak to zaimplementować? Otóż najpierw potrzebny jest interfejs, który będą wspierały nasze wtyczki, w naszym prostym przykładzie może to być:
    public interface IDoSth
    {
        string DoSth();
    }
Każda wtyczka będzie musiała posiadać publiczną klasę wspierającą ten interfejs, np.:
namespace PluginLibrary1
{
    public class Class1 : IDoSth
    {
        #region IDoSth Members
        public string DoSth()
        {
            return "Hello from Plugin Class";
        }
        #endregion
    }
}
Teraz czas na implementację głównego programu, który przejrzy lokalny katalog, załaduje wszystkie assembly pasujące do wzorca: „Plugin*.dll”. Następnie przejrzy publiczne typy (klasy) i wybierze te, które wspierają interfejs IdoSth. Powoła instancje tych typów i pobierze odpowiednie teksty z wtyczek i wyświetli je na ekranie. Czyli uzyskamy kod podobny do:
class Program
{
    static void Main()
    {
        //selecting current directory
        DirectoryInfo di = new DirectoryInfo(".");
        //checking all DLL files in the current directory that start from "Plugin"
        foreach(FileInfo fi in di.GetFiles("Plugin*.dll"))
        {
            //loading of the Plugin directory
            Assembly pluginAssembly=Assembly.LoadFrom(fi.FullName);
            //checking all public types from loaded assembly
            foreach( Type pluginType in pluginAssembly.GetExportedTypes())
            {
                //now we are checking whether particular type implements 
                //IDoSth interface
                if (pluginType.GetInterface(typeof(IDoSth).Name)!=null)
                {
                    //creating the instance of selected type
                    IDoSth TypeLoadedFromPlugin = (IDoSth)Activator.CreateInstance( pluginType );
                    //do sht with the plugin
                    Console.WriteLine(TypeLoadedFromPlugin.DoSth());
                }
            }
        }
        Console.ReadLine();
    }
}

Proste, prawda? To oczywiście dopiero czubek góry lodowej, ale mam nadzieję, że główną ideę udało mi się przekazać, przemycając dodatkowo trochę odnośnie ładowania i przeglądania assembly.


Promuj

6 komentarzy:

  1. A ja bym poprosił o to co jest poniżej tego czubka ;-)

    OdpowiedzUsuń
  2. Dla standardowych rozwiązań bardzo dobre rozwiązanie, dla już większych możliwości polecam MEF.

    OdpowiedzUsuń
  3. o ;->
    skończę aktualny projekt to sobie to obadam, bo i tak planowałem napisać wtyczkowalną aplikacje, a póki co miała się opierać na dosyć dziwacznym rozwiązaniu ;-)

    OdpowiedzUsuń
  4. Witam,
    No może z tym czubkiem góry lodowej, to przesadziłem... mechanizm który pokazałem działa i po prostu trzeba go uzupełnić o takie elementy jak:
    - obsługę błędów,
    - bezpieczeństwo i ograniczone zaufanie do czyjegoś kodu,
    - identyfikację wtyczek,
    - manager wtyczek,
    - wyładowanie (unload) nie potrzebnych wtyczek,
    - inne ...

    Oczywiście jest jeszcze MEF, czyli Managed Extensibility Framework, ale przyznam, że jeszcze nim się nie zajmowałem.

    W każdym razie dzięki za komentarze i być może coś się jeszcze w tym temacie na blogu pojawi.

    OdpowiedzUsuń
  5. Świetny artykuł na temat bardzo przydatnego mechanizmu :)

    OdpowiedzUsuń
    Odpowiedzi
    1. Cieszę się, ze Ci się podobał, jeżeli masz ochotę poczytać na ten temat więcej, to rozwinięcie tego tematu znajduje się tutaj: http://maciej-progtech.blogspot.com/2012/03/wprowadzenie-do-managed-add-in.html .

      Usuń

Posty powiązane / Related posts