Sdílet prostřednictvím


Postupy: Implementace architektury komponenty modulu plugin pomocí reflexe (C++/CLI)

Následující příklady kódu ukazují využívání reflexe pro implementaci jednoduché architektury "plug-in".První soupis je aplikace a druhý je modul plug-in.Aplikace je formulář složený z více dokumentů, který se sám naplňuje pomocí všech tříd založených na formuláři, nalezených v knihovně DLL modulu plug-in, poskytnutém jako argument příkazového řádku.

Aplikace se pokouší načíst zadané sestavení pomocí metody Assembly.Load.V případě úspěchu jsou typy uvnitř sestavení vyčteny pomocí metody Assembly.GetTypes.Každý typ je potom zkontrolován na kompatibilitu pomocí metody Type.IsAssignableFrom.V tomto příkladu musí být nalezené třídy v zadaném sestavení odvozeny od třídy Form, aby byly kvalifikovány jako modul plug-in.

Kompatibilní třídy jsou potom konkretizovány metodou Activator.CreateInstance, která přijímá Type jako argument a vrací ukazatel na novou instanci.Každá nová instance je pak připojena k formuláři a zobrazena.

Všimněte si, že metoda Load nepřijímá názvy sestavení, které obsahují příponu názvu souboru.Hlavní funkce v aplikaci ořeže všechny zadané přípony, takže následující příklad kódu pracuje v obou případech.

Příklad

Následující kód definuje aplikaci, která přijímá moduly plug-in.Název sestavení musí být uveden jako první argument.Toto sestavení by mělo obsahovat alespoň jedem veřejný typ odvozený od Form.

// plugin_application.cpp
// compile with: /clr /c
#using <system.dll>
#using <system.drawing.dll>
#using <system.windows.forms.dll>

using namespace System;
using namespace System::Windows::Forms;
using namespace System::Reflection;

ref class PluggableForm : public Form  {
public:
   PluggableForm() {}
   PluggableForm(Assembly^ plugAssembly) {
      Text = "plug-in example";
      Size = Drawing::Size(400, 400);
      IsMdiContainer = true;

      array<Type^>^ types = plugAssembly->GetTypes( );
      Type^ formType = Form::typeid;

      for (int i = 0 ; i < types->Length ; i++) {
         if (formType->IsAssignableFrom(types[i])) {
            // Create an instance given the type description.
            Form^ f = dynamic_cast<Form^> (Activator::CreateInstance(types[i]));
            if (f) {
               f->Text = types[i]->ToString();
               f->MdiParent = this;
               f->Show();
            }
         }
      }
   }
};

int main() {
   Assembly^ a = Assembly::LoadFrom("plugin_application.exe");
   Application::Run(gcnew PluggableForm(a));
}

Následující kód definuje tři třídy, odvozené z Form.Když je název výsledného sestavení předán spustitelnému souboru v předchozí ukázce, každá z těchto tří tříd bude prozkoumána a konkretizována, bez ohledu na fakt, že byly hostitelské aplikaci v době kompilace všechny neznámé.

// plugin_assembly.cpp
// compile with: /clr /LD
#using <system.dll>
#using <system.drawing.dll>
#using <system.windows.forms.dll>

using namespace System;
using namespace System::Windows::Forms;
using namespace System::Reflection;
using namespace System::Drawing;

public ref class BlueForm : public Form {
public:
   BlueForm() {
      BackColor = Color::Blue;
   }
};

public ref class CircleForm : public Form {
protected:
   virtual void OnPaint(PaintEventArgs^ args) override {
      args->Graphics->FillEllipse(Brushes::Green, ClientRectangle);
   }
};

public ref class StarburstForm : public Form {
public:
   StarburstForm(){
      BackColor = Color::Black;
   }
protected:
   virtual void OnPaint(PaintEventArgs^ args) override {
      Pen^ p = gcnew Pen(Color::Red, 2);
      Random^ r = gcnew Random( );
      Int32 w = ClientSize.Width;
      Int32 h = ClientSize.Height;
      for (int i=0; i<100; i++) {
         float x1 = w / 2;
         float y1 = h / 2;
         float x2 = r->Next(w);
         float y2 = r->Next(h);
         args->Graphics->DrawLine(p, x1, y1, x2, y2);
      }
   }
};

Viz také

Referenční dokumentace

Reflexe (C++/CLI)