Schreiben eines Plug-Ins
Sie können mit einer der folgenden Methoden Plug-Ins erstellen:
Power Platform Entwicklungstools bieten eine moderne Möglichkeit, Plug-Ins zu erstellen. Bei den Tools, auf die hier verwiesen wird, handelt es sich um Power Platform Tools für Visual Studio und Power Platform CLI. Diese beiden Power Platform Tools generieren ähnlichen Plug-In-Code, sodass die Umstellung von einer Toolmethode auf die andere ziemlich einfach und nachvollziehbar ist.
Verwenden Sie Power Platform Tools für Visual Studio, um schnell Vorlagen-Plug-In-Code zu erstellen und ein Plug-In zu registrieren (bereitzustellen). Ein Schnellstart-Artikel ist verfügbar, der Ihnen zeigt, wie das geht. Verwenden Sie dieses Tool, wenn Sie in Visual Studio arbeiten möchten.
Verwenden Sie Power Platform CLI, um ein einfaches (Visual Studio kompatibles) Plug-In-Projekt mit Plug-In-Codevorlage mit einem einzigen pac plugin Befehl zu erstellen. Anschließend verwenden Sie interaktiv das Tool zur Plug-In-Registrierung mit dem Befehl pac tool prt, um das Erstellen bei Microsoft Dataverse zu registrieren. Verwenden Sie dieses CLI-Toolset, wenn Sie gerne in einem Terminalfenster oder Visual Studio Code arbeiten.
Schreiben Sie Code manuell mit Visual Studio oder Ihrem bevorzugten Editor. Dieser Artikel konzentriert sich auf das Schreiben von Code mit Dataverse-APIs, die vorgestellten Konzepte gelten jedoch auch für die Plug-In-Entwicklung mit unseren zuvor erwähnten Tools.
IPlugin-Schnittstelle
Ein Plug-In ist eine kompilierte Klasse in einer Assembly, die für .NET Framework 4.6.2 erstellt wurde. Jede Klasse in einem Plug-in-Projekt, die auf einem Ereignis Pipeline Schritt registriert ist, muss die Schnittstelle IPlugin implementieren, die eine einzelne Methode IPlugin.Execute definiert.
public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
Die Execute-Methode akzeptiert einen einzelnen IServiceProvider-Parameter. Der IServiceProvider
hat eine einzelne Methode: GetService. Verwenden Sie diese Methode, um verschiedene Typen von Diensten abzurufen, die Sie in Ihrem Code verwenden können.
Weitere Informationen: Dienste, die Sie in Ihrem Code verwenden können
Wichtig
Bei der Ableitung vom IPlugin
sollte die Klasse statusfrei geschrieben sein. Dies liegt daran, dass die Plattform eine Klasseninstanz zwischenspeichert und sie aus Leistungsgründen erneut verwendet. Eine einfache Möglichkeit, sich dies vorzustellen, besteht darin, dass Sie keine Eigenschaften oder Methoden der Klasse hinzufügen sollten, und alles sollte in der Execute
-Methode eingeschlossen sein.
Wenn zur Plug-In-Erstellung die Power Platform Tools-Erweiterung oder Power Platform CLI verwendet wird, implementiert die generierte PluginBase
-Klasse die IPlugin
-Schnittstelle.
Es gibt einige Ausnahmen von der Aussage über das Hinzufügen von Eigenschaften oder Methoden im obigen Hinweis. Sie können zum Beispiel eine Eigenschaft haben, die eine Konstante darstellt, und Sie können Methoden haben, die von der Execute
Methode aufgerufen werden. Es ist wichtig, dass Sie nie irgendeine Serviceinstanz oder Kontextdaten als Eigenschaft in Ihrer Klasse speichern. Diese Werte ändern sich bei jedem Aufruf, und Sie möchten nicht, dass diese Daten zwischengespeichert und auf darauf folgende Aufrufe angewendet werden.
Weitere Informationen: Entwickeln von IPlugin-Implementierungen als statusfrei
Konfigurationsdaten Ihrem Plug-In übergeben
Wenn Sie ein Plug-in registrieren, können Sie optional Konfigurationsdaten angeben, die zur Laufzeit an das Plug-in übergeben werden. Konfigurationsdaten ermöglichen es Ihnen zu definieren, wie eine bestimmte Instanz eines registrierten Plug-In sich verhalten soll. Diese Informationen werden als Zeichenfolgendaten den Parametern im Konstruktor Ihrer Klasse übergeben. Es gibt zwei Parameter namens unsecure
und secure
. Verwenden Sie die ersten unsecure
-Parameter für Daten, bei denen es Ihnen nichts ausmacht, wenn andere sie sehen können. Verwenden Sie den zweiten secure
-Parameter für vertrauliche Daten.
Der folgende Code zeigt die drei möglichen Konstrukteursignaturen für eine Plug-In-Klasse namens MyPlugin.
public MyPlugin() {}
public MyPlugin(string unsecure) {}
public MyPlugin(string unsecure, string secure) {}
Die sicheren Konfigurationsdaten werden in einer separaten Tabelle gespeichert, die nur Systemadministratoren lesen dürfen.
Weitere Informationen: Registrieren des Plug-In-Schritts > Konfigurationsdaten festlegen
Abstrakte PluginBase-Klasse
Der PluginBase
-Klasse implementiert die IPlugin
-Schnittstelle. Wir bieten diese Klasse an, da sie ein robustes Programmiermuster implementiert, das sich in kommerziellen Lösungen bewährt hat. Die Verwendung dieser Klasse in Ihrem Plug-In-Code wird empfohlen, ist jedoch optional.
Die Klasse ist in keiner SDK-Assembly verfügbar, sondern Sie müssen die Klasse mit einem unserer Tools generieren. Um die Klasse zu generieren, erstellen Sie ein Plug-In-Projekt in der Power Platform Tools-Erweiterung für Visual Studio oder führen Sie den Power Platform-CLI-Befehl pac plugin init
aus. Im generierten Projekt finden Sie eine PluginBase.cs-Datei.
Weitere Informationen: pac-Plug-In, Schnellstart: Ein Plug-In mit Power Platform Tools einrichten
Wichtig
Die von der Power Platform Tools-Erweiterung generierte PluginBase
-Klasse und die Power Platform-CLI weisen leicht unterschiedliche Klassenmitgliedssignaturen auf. Es ist am besten, sich für die eine oder das Möglichkeit zu entscheiden und während der gesamten Entwicklung Ihres Plug-In-Codes dabei zu bleiben. Beide Versionen der Klasse haben die gleiche Funktionalität und funktionieren ähnlich.
Dieses Klassendiagramm bietet eine visuelle Darstellung der wichtigsten Schnittstellen und Klassen im Zusammenhang mit PluginBase
.
Die Plugin1
-Beispielklasse (im Diagramm) leitet sich von PluginBase
ab. Sie geben dieser Plugin1
-Klasse normalerweise Ihren eigenen benutzerdefinierten Namen und fügen Code hinzu, um die ExecuteDataversePlugin
-Methode und den Klassenkonstruktor zu implementieren. Die LocalPluginContext
-Klasse wird automatisch mit den angegebenen Dienstreferenzen und Endpunkten initialisiert, die für Ihr Plug-In verfügbar sind. Wenn Sie die IPlugin
-Schnittstelle implementieren würden, müssten Sie Code schreiben, um alle diese Dienste und Endpunkte vor der Verwendung zu initialisieren.
Dienste, die Sie in Ihrem Code verwenden können
Normalerweise müssen Sie in Ihrem Plug-In:
- Auf die an Ihr Plug-In übergebenen Kontextdaten zugreifen, um Informationen über die Entität und die Nachrichtenanforderung herauszufinden, die das Ereignis verursacht und Ihr Plug-In aufgerufen hat. Diese Daten werden als Ausführungskontext bezeichnet.
- Greifen Sie mit SDK für .NET-Aufrufe auf den Organisationswebdienst zu, um Meldungsanforderungsvorgänge wie Abfragen, Erstellen, Aktualisieren, Löschen und mehr auszuführen.
- Schreiben Sie Meldungen an den Ablaufverfolgungsdienst, sodass Sie auswerten können, wie Ihr Plug-In-Code ausgeführt wird.
Hinweis
Alle Dataverse-Dienste, die Ihr Plug-In normalerweise nutzen würde, und der Plug-In-Ausführungskontext sind vorkonfiguriert und für Ihren Plug-In-Code verfügbar, wenn Sie Ihr Plug-In von der PluginBase
-Klasse ableiten.
Im IServiceProvider.GetService Methode bietet Ihnen eine Möglichkeit, bei Bedarf auf Dienstverweise zuzugreifen, die im Ausführungskontext übergeben werden. Um eine Instanz eines Dienstes zu erhalten, rufen Sie die Methode GetService
auf und übergeben den Typ des Dienstes. In den nächsten Abschnitten erfahren Sie mehr über diese Methode.
Context-Ausführungen
Der Ausführungskontext enthält eine Fülle an Informationen, die ein Plug-In vielleicht braucht. Der Kontext wird mit dem folgenden Code abgerufen.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
Weitere Informationen: IPluginExecutionContext, Grundlegendes zum Ausführungskontext
Organisationswebdienst
Neben den im Ausführungskontext übergebenen Daten können Dataverse Tabellenzeilendaten mithilfe von SDK-Aufrufen an den Organisationswebdienst aus dem Plug-In-Code ausgelesen oder geschrieben werden. Versuchen Sie nicht, die Web-API zu verwenden, da diese in Plug-ins nicht unterstützt wird. Authentifizieren Sie den Benutzer nicht, bevor Sie auf die Webdienste zugreifen, da der Benutzer vor der Ausführung des Plug-ins vorauthentifiziert wird.
Weitere Informationen: Tabellenvorgänge, Meldungen verwenden
Verwenden Sie den folgenden Code, um einen Objektverweis zum Organisationswebdienst zu erhalten:
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService orgService = serviceFactory.CreateOrganizationService(context.UserId);
Ablaufverfolgungsdienst
Verwenden Sie den Tracing-Dienst, um Nachrichten in die PluginTraceLog-Tabelle zu schreiben, sodass Sie die Protokolle überprüfen können, um zu verstehen, was beim Ausführen des Plug-ins passiert ist.
Wichtig
Sie müssen zuerst die Ablaufverfolgungsprotokollierung in Ihrer Umgebung aktivieren, bevor Sie in die Protokolle schreiben oder sie anzeigen können. Weitere Informationen: Nachverfolgung und Protokollierung
Um in das Tracelog zu schreiben, müssen Sie eine Instanz des Tracing-Dienstes abrufen. Der folgende Code zeigt, wie Sie eine Instanz des Tracing-Dienstes abrufen, indem Sie die IServiceProvider.GetService Methode verwenden.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
Um die Ablaufverfolgung zu schreiben, verwenden Sie die ITracingService.Trace Methode verwenden.
tracingService.Trace("Write {0} {1}.", "your", "message");
Weitere Informationen finden Sie unter: Ablaufverfolgung verwenden, Ablaufverfolgung und Protokollierung
Sonstige Dienste
Wenn Sie ein Plug-in schreiben, das die Azure Service Bus-Integration nutzt, verwenden Sie den Benachrichtigungsdienst, der die Schnittstelle IServiceEndpointNotificationService implementiert. Diese Schnittstelle wird hier jedoch nicht beschrieben.
Weitere Informationen: Azure-Integration
Alles zusammenfügen
Aus den zuvor beschriebenen Plug-In-Konzepten ergibt sich ein Plug-In-Code, der wie folgt aussieht.
public class MyPlugin : PluginBase
{
// Constructor
public MyPlugin(string unsecureConfiguration, string secureConfiguration)
: base(typeof(MyPlugin))
{ }
protected override void ExecuteDataversePlugin(ILocalPluginContext localPluginContext)
{
if (localPluginContext == null)
{
throw new ArgumentNullException(nameof(localPluginContext));
}
var context = localPluginContext.PluginExecutionContext;
var serviceFactory = localPluginContext.OrgSvcFactory;
var tracingService = localPluginContext.TracingService;
try
{
// TODO Plug-in business logic goes here. You can access data in the context,
// and make calls to the Organization web service using the Dataverse SDK.
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("The following error occurred in MyPlugin.", ex);
}
catch (Exception ex)
{
tracingService.Trace("MyPlugin: error: {0}", ex.ToString());
throw;
}
}
}
Sie können diese beiden Methoden der Plug-In-Implementierung in unserem FollowupPlugin-Codebeispiel überprüfen. Weitere Informationen zur Behandlung von Ausnahmen in Plug-Ins finden Sie unter Behandeln von Ausnahmen in Plug-Ins.
Der Plug-In-Entwurf wirkt sich auf die Leistung aus
Wenn Sie Ihr Plug-in schreiben, ist es wichtig, dass es effizient und schnell ausgeführt wird. Unabhängig davon, wie lange die Ausführung Ihres Plug-Ins dauert, muss der Endbenutzer, der den Nachrichtenvorgang (der Ihr Plug-In ausgelöst hat) aufgerufen hat, warten. Dataverse verarbeitet nicht nur den Nachrichtenvorgang, sondern führt auch alle registrierten synchronen Plug-Ins in der Pipeline aus, einschließlich Ihres Plug-Ins. Wenn die Ausführung von Plug-ins zu lange dauert oder zu viele Plug-ins in einer Pipeline registriert sind, kann diese Auswirkung auf die Leistung dazu führen, dass die Benutzeroberfläche der Anwendung nicht reagiert oder schlimmstenfalls ein Timeout-Fehler mit Pipeline-Rollback eintritt.
Wichtig
Plug-Ins müssen eine Ausführungszeitbegrenzung und Ressourcenbeschränkungen einhalten. Weitere Informationen: Analysieren der Plug-In-Leistung
Typen mit früher Bindung im Plug-In-Code verwenden
Sie können optional Typen mit früher Bindung in Plug-In-Code verwenden. Fügen Sie die generierte Datei mit den Typen in Ihr Plugin-Projekt ein. Alle in der Sammlung InputParameters des Ausführungskontexts bereitgestellten Tabellentypen sind spät gebundene Typen. Sie müssten diese Typen mit später Bindung in solche mit früher Bindung konvertieren.
Wenn Sie wissen, dass der Target
Parameter für eine Kontotabelle steht, können Sie zum Beispiel Folgendes tun. In diesem Beispiel ist „Konto“ ein Typ mit früher Bindung.
Account acct = context.InputParameters["Target"].ToEntity<Account>();
Sie sollten aber nie versuchen, den Wert mit einem früh gebundenen Typ festzulegen. Wenn Sie dies tun, tritt ein SerializationException auf.
context.InputParameters["Target"] = new Account() { Name = "MyAccount" }; // WRONG: Do not do this.
Siehe auch
Verarbeiten von Ausnahmen
Registrieren eines Plug-Ins
Debuggen von Plug-Ins
Lernprogramm: Schreiben und Registrieren eines Plugins
Beste Praktiken und Anleitungen hinsichtlich Plug-In und Workflow-Entwicklung
Hinweis
Können Sie uns Ihre Präferenzen für die Dokumentationssprache mitteilen? Nehmen Sie an einer kurzen Umfrage teil. (Beachten Sie, dass diese Umfrage auf Englisch ist.)
Die Umfrage dauert etwa sieben Minuten. Es werden keine personenbezogenen Daten erhoben. (Datenschutzbestimmungen).