Dataverse-Erweiterbarkeit
In diesem Thema werden wir die für Entwickler verfügbaren Erweiterungspunkte von Dataverse untersuchen. Die Architektur von Dataverse richtet eine nachrichtengesteuerte Architektur für die Verarbeitung von Anforderungen ein. Jede Anforderungsnachricht wird über eine Ereignispipeline verarbeitet, die Erweiterungspunkte zum Ausführen benutzerdefinierter Geschäftslogik hat, die durch Plug-Ins implementiert wird. Viele Nachrichten werden standardmäßig bereitgestellt, und bei jeder Erstellung einer neuen Tabelle, werden zur Unterstützung dieser Tabelle neue Nachrichten hinzugefügt. Durch Erstellen einer benutzerdefinierten API erstellen Sie auch eine neue Nachricht.
Ein Schlüsselkonzept ist, dass unabhängig davon, wie auf Daten zugegriffen wird, diese immer als Nachricht über die Ereignispipeline verarbeitet werden und jede benutzerdefinierte Geschäftslogik ausgeführt wird. Dies gilt unabhängig davon, ob Sie die Benutzeroberfläche einer App oder eine der APIs verwenden oder Verwaltungsvorgänge wie den Datenimport ausführen. Es gibt keine Möglichkeit zum Ändern der Dataverse-Daten direkt, die das laufende System oder die registrierte benutzerdefinierte Logik umgehen würden.
Die Dataverse-API verwenden
Dataverse bietet zwei Arten von APIs, mit denen Entwickler mit Daten interagieren können: Web-API und Organisationsdienst. Im Folgenden wird ein allgemeiner Überblick über beide geboten:
Dataverse-Web-API
Die Web-API ist an einem OData v4 RESTful-Endpunkt verfügbar. Verwenden Sie diese Option für jede Programmiersprache, die HTTP-Anforderungen und die Authentifizierung mit OAuth 2.0 unterstützt. Finden Sie weitere Beispiele.
Dataverse Organization-Service
Der Organisationsdienst ist ein .NET SDK mit .NET-Assemblys, die von Microsoft zusammen mit typisierten Klassengeneratoren für Tabellenklassen bereitgestellt werden.
Bei einem Organisationsdienst von einem Dataverse-Plug-In instanziiert sich der Dienst und steht dem Plug-In-Code zur Verfügung, ohne dass eine Authentifizierung erforderlich ist. Sie würden den serviceProvider verwenden, der an das Plug-In übergeben wird, um eine Instanz der Organisations-Dienstfactory (IOrganizationService) abzurufen, um eine Instanz aus Ihrer Plugin-Logik abzurufen. Über die Fabrik können Sie eine Instanz des Organisationsdienstes abrufen. Das Folgende ist ein Beispiel für ein einfaches Plug-In, das eine Instanz abruft und diese zum Erstellen einer Kontotabellenzeile verwendet.
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext pluginContext = serviceProvider.Get<IPluginExecutionContext>();
IOrganizationServiceFactory factory = serviceProvider.Get<IOrganizationServiceFactory>();
IOrganizationService orgService = serviceProvider.GetOrganizationService(pluginContext.UserId);
Entity newAccount = new Entity("account");
newAccount["name"] = "Fourth Coffee";
Guid accountid = orgService.Create(newAccount);
}
Sie können den Organisationsdienst auch außerhalb von Plug-Ins verwenden, zum Beispiel über ein benutzerdefiniertes ASP.NET-Portal, eine Azure Function oder sogar eine Konsolenanwendung. Für diese Art von Anwendungen würden Sie den Organisationsdienst vom Dataverse-ServiceClient verwenden, der Unterstützung für Anwendungen bietet, die .NET Full Framework 4.6.2, 4.7.2, 4.8 und .NET Core 3.0, 3.1, 5.0, 6,0 verwenden. Die ServiceClient-Klasse implementiert die IOrganizationService-Schnittstelle. Der ServiceClient implementiert auch IOrganizationServiceAsync2, wodurch auch asynchrone Versionen der Methoden verfügbar werden.
Im folgenden Beispiel wird eine Instanz von ServiceClient abgerufen und eine neue Kontotabellenzeile erstellt.
ServiceClient serviceClient =
new ServiceClient("Url=https://yourenv.crm.dynamics.com;AuthType=OAuth;AppId=;RedirectUri=http://localhost ;LoginPrompt=Always");
Entity newAccount = new Entity("account");
newAccount["name"] = "Fourth Coffee";
Guid accountid = serviceClient.Create(newAccount);
Es sind zudem weitere Beispiele für die Verwendung des Organisationsdienstes verfügbar. Sie können auch weitere Details zu den verfügbaren Verbindungszeichenfolgen und Optionen prüfen.
Die APIs unterstützen neben der Unterstützung von FetchXML auch ihre eigenen Ansätze zum Erstellen von Datenabfragen. FetchXML ist eine proprietäre Abfragesprache, die in Dataverse verwendet wird. Mit der FetchXML-Sprache können komplexe Abfragen über verwandte Tabellen hinweg erstellt und Dataverse-spezifische Bedingungen und Operatoren verwendet werden. Der Power Automate Dataverse-Konnektor unterstützt FetchXML auch.
Ereignis‑Pipeline
Wenn Sie eine Aktion ausführen, z. B. einen Datensatz in einer App erstellen oder einen Datensatz mithilfe der API erstellen, wird von Dataverse eine Nachricht zum Erstellen verarbeitet. Die Nachricht wird in der Ereignispipeline verarbeitet, die einen konsistenten Satz von Phasen bereitstellt, die die Nachricht durchläuft. An jede Stufe mit Ausnahme der Hauptoperation kann ein Plug-In angehängt werden, um benutzerdefinierte Logik auszuführen. Die folgenden Phasen werden unterstützt, wenn eine Nachricht oben beginnt und die Phasen der Pipeline durchläuft:
Wenn Sie genau wissen, wie Nachrichten verarbeitet werden, können Sie das Verhalten besser verstehen und wissen, wie und wo Sie benutzerdefinierte Logik am besten implementieren können. Das Verständnis der Pipeline ist auch wichtig, um zu erkennen, wie Plug-Ins und benutzerdefinierte APIs passen. Informieren Sie sich über Details zum Ereignisframework.
Plug-Ins erstellen
Plug-Ins sind .NET-Klassen, die eine IPlugin-Schnittstelle bereitgestellt von den Dataverse SDK-Assemblys implementieren. Für diese Schnittstelle müssen Sie nur eine Methode namens „Ausführen“ implementieren. Das Folgende ist ein Beispiel für eine minimale Implementierung.
public sealed class MyFirstPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
//Business Logic
}
}
Die Methode Ausführen hat einen Parameter vom Typ IServiceProvider. Diese Schnittstelle hat eine Methode GetService, die Sie verwenden können, um Dienste abzurufen, die für ein Plug-In verfügbar sind. Im Folgenden finden Sie Beispiele für den verfügbaren Dienst:
IPluginExecutionContext – Dadurch erhalten Sie Zugriff auf die zu verarbeitende Nachricht und Informationen zum Anforderer.
ITracingService – Auf diese Weise können Sie zu Diagnosezwecken in das Ablaufverfolgungsprotokoll schreiben.
IOrganizationServiceFactory – Damit haben Sie Zugriff auf einen OrganizationService für den Zugriff auf Daten über das Plug-In.
Das Folgende ist ein Beispiel für die Verwendung von GetService, um den Ausführungskontext zu erhalten:
IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext));
Mit context.InputParameters können Sie auf die ursprüngliche Nachricht und den Kontext zugreifen. OutputParameters können Ihnen Zugriff auf das geben, was an den Aufrufer zurückgegeben wird.
Ein gutes Verständnis des Ausführungskontexts ist für einen Plug-In-Entwickler von grundlegender Bedeutung. Erfahren Sie mehr über den Ausführungskontext.
Damit ein Plug-In ausgeführt werden kann, muss es registriert sein, damit es für eine bestimmte Nachricht ausgeführt werden kann. Dazu können Sie das Plug-in Registration Tool verwenden.
Benutzerdefinierte APIs
Operationen in Dataverse sind als Nachrichten definiert. Benutzerdefinierte APIs bieten eine Code-First-Methode zum Definieren neuer Nachrichten, mit denen Sie Dataverse-Webdienste erweitern können. Diese Nachrichten können dann wie die Systemnachrichten aufgerufen werden, um jedoch eine benutzerdefinierte Geschäftslogik auszuführen. Wenn Sie beispielsweise bestimmte Anforderungen für die Suche nach einem Kunden mithilfe einer vordefinierten Folge von API-Aufrufen haben, können Sie anstelle der Implementierung dieser Reihenfolge durch jeden API-Aufrufer eine benutzerdefinierte findcustomer-API implementieren. Die findcustomer-API würde nun die erforderliche Logik implementieren, um nach dem Kunden zu suchen und die Ergebnisse zurückzugeben. Dies würde sicherstellen, dass jede App nicht herausfinden muss, wie sie einen Kunden findet und dies inkonsistent tut, sondern die benutzerdefinierte API aufrufen kann, die die Suchanforderungen bei jeder Gelegenheit auf die gleiche Weise verarbeitet. Und wenn Änderungen erforderlich sind, müssen diese nur an einer Stelle implementiert werden.
Um eine neue benutzerdefinierte API zu definieren, erstellen Sie zunächst einen benutzerdefinierten API-Datensatz. Dies kann über das Entwicklerportal, über Code oder mithilfe von Dataverse-Lösungen erfolgen. Beim Erstellen des Datensatzes identifizieren Sie den benutzerdefinierten API-Namen sowie die Anforderungs‑ und Antwortparameter.
Um die Logik der benutzerdefinierten API zu implementieren, erstellen Sie ein Plug-In und registrieren es in der Hauptoperationsphase der Pipeline. Die benutzerdefinierte API-Implementierung ist das einzige Szenario, in dem ein Plug-In in der Hauptoperationsphase registriert werden kann. Ein Beispiel dafür finden Sie später in der Übung.
Sie können die benutzerdefinierte Nachricht von den Dataverse-APIs Power Apps und Power Automate verwenden, nachdem sie implementiert wurde. Im Folgenden finden Sie ein Beispiel für die Verwendung der benutzerdefinierten findcustomer-API aus C#.
var req = new OrganizationRequest("fabrikam_findcustomer")
{
["CustomerName"] = "Contoso",
["CustomerAddress"] = "1 Redmond Way"
};
var resp = serviceClient.Execute(req);
Sie können auch kein Plug-In implementieren und zulassen, dass die benutzerdefinierte API verwendet wird, um andere Automatisierungen auszulösen. Wenn Sie beispielsweise eine benutzerdefinierte API erstellen, die Daten zu einem Ereignis enthält, das in einem anderen System aufgetreten ist, kann dieses System diese API in Dataverse aufrufen, wo viele verschiedene Integrationspunkte mit Azure, Web Hooks, Power Automate oder asynchronen Plug-Ins in der API andere Automatisierungen initiieren können.