16. Juni 2013 · von Andreas Klein

Erklärt: Plugins registrieren Plugins

In C# entwickelte Plugins sind die Lösung um Dynamics CRM serverseitig mit erweiterter Funktionalität zu bereichern, wenn Workflows und Co. nicht mehr ausreichen. Plugin schreiben, ins CRM einklinken und los geht es. In den meisten Fällen deckt dies genau die Anforderung an die Erweiterung von CRM ab. Es gibt aber Situationen, in denen man mehr Flexibilität benötigt, z.B. das registrieren oder deregistrieren von Plugins dynamisch zur Laufzeit, getriggert über ein Plugin welches auf Create, Update oder Delete Events reagiert.
Ein Beispiel: Eine häufig vorkommende Anforderung im CRM ist es Datensätze einer Entität mit einer eindeutigen durchlaufenden Nummer zu versehen. Für Rechnungen, Service Calls etc. bringt CRM schon eine Basisfunktionalität mit. Leider lässt sich das Nummernschema kaum beeinflussen. Hier ist oft eine individuelle Lösung gefragt.
Die Idee ist nun, für einen solchen Nummernkreis einen eigenen Datensatz mit Startwert, Stellenanzahl, Wertebereich etc. zu erstellen. In diesem Nummernkreis wird die Zielentität und das Attribut welches die generierte Nummer enthalten soll hinterlegt. Beim Anlegen eines Nummernkreises wird über den Create Event ein Plugin getriggert, welches dann das Plugin zur Nummerngenerierung für die Zielentität registriert. Beim Löschen des Datensatzes wird das Plugin zur Nummerngenerierung dann deregistriert. Das Deaktivieren bzw. Aktivieren eines Nummerkreises triggert entsprechend das Deaktivieren bzw. Aktivieren des Plugins für die Zielentität.
Damit kann die Konfiguration und Steuerung der Nummernkreise für beliebige Entitäten und Attribute in CRM selbst erfolgen.

Umsetzung

Zunächst benötigen wir eine eigene Entität für den Nummernkreis mit den entsprechenden Attributen:

nummernkreis-1

Incl. der Informationen zu den SDK Nachrichtenverarbeitungsschritten und ein Plugin, welches beim Anlegen eines Datensatzes der Zielentität aus dem dazugehörigen Nummernkreis die laufende Nummer ausliest, hochzählt und abspeichert.

Soweit der einfache Teil… bis hierher noch nichts Besonderes. Jetzt müssen wir aber dafür sorgen, dass das Plugin beim CRM registriert wird, und zwar von einem Plugin welches auf den Create Event des Nummernkreises reagiert.

Dazu holen wir uns zunächst das primäre Objekt in dem alle wesentlichen Parameter wie z.B. Zielentität und Attribut gespeichert sind und bauen uns mit deren Hilfe einen eindeutigen Namen für unser Plugin auf.

// Get primary object
ang_number myNumber = (from u in context.CreateQuery<ang_number>() where u.Id == pluginContext.PrimaryEntityId select u).Single();

myNumber.ang_number1 = myNumber.ang_startValue;
myNumber.ang_CurrentYear = CultureInfo.InvariantCulture.Calendar.GetYear(DateTime.Now);

//Build SdkMessageProcessingStep name
string stepName = "AutoNumberGenerator PostCreate [" + myNumber.ang_entity + "." + myNumber.ang_field + "]";

Danach identifizieren wir das Ziel-Plugin, also das Plugin für das wir einen SDK Nachrichtenverarbeitungsschritt (sdkMessageProcessingStep) registrieren wollen und prüfen erst, ob es bereits einen entsprechenden sdkMessageProcessingStep gibt.

//Get PluginTypeID for AutoNumberGenerator.Plugins.NumberGenerator
PluginType plugin = (from u in context.CreateQuery() where u.TypeName == "AutoNumberGenerator.Plugins.NumberGenerator" select u).Single();

//Check if step  + stepName +  already exists
int sdkMessageProcessingSteps = (from u in context.CreateQuery()
                                 where u.IsHidden.Value == false &&
                                       u.Name == stepName &&
                                       u.EventHandler.Id == plugin.Id
                                 select u).ToList().Count;

Wenn alles glatt geht kann nun der neue sdkMessageProcessingStep registriert werden. Hierzu holen wir uns zunächst die passenden Event und Filter ID’s welche festlegen, worauf das Plugin triggern soll – in unserem Fall ein Create Event:

if (sdkMessageProcessingSteps == 0)
{
  //Register new step 
  SdkMessage message = (from u in context.CreateQuery() where u.Name == "Create" select u).Single();
  SdkMessageFilter messageFilter = (from u in context.CreateQuery()
                                    where u.SdkMessageId.Id == message.Id &&
                                          u.PrimaryObjectTypeCode == myNumber.ang_entity &&
                                          (u.Availability == 0 || u.Availability == 2) &&
                                          u.IsCustomProcessingStepAllowed.Value == true
                                    select u).Single();

Der Rest ist einfach: SdkMessageProcessingStep erzeugen, Properties einstellen und abspeichern:

  SdkMessageProcessingStep step = new SdkMessageProcessingStep();

  step.Name = stepName;
  step.Description = stepName;
  step.Rank = 1;
  step.Stage = new OptionSetValue(20);

  step.EventHandler = plugin.ToEntityReference();
  step.SdkMessageId = message.ToEntityReference();
  step.SdkMessageFilterId = messageFilter.ToEntityReference();

  context.AddObject(step);
}
context.UpdateObject(myNumber);
context.SaveChanges();

Die Plugins für das Update bzw. Delete Event folgen dem gleichen Schema.

Wichtig ist in diesem Zusammenhang ggf. noch, unter welchem Account das Plugin ausgeführt wird. Sind die Berechtigungen für die Nummernkreis Entität z.B. so eingestellt, dass Diese nur von einem Administrator geändert werden dürfen, so funktioniert in diesem Fall natürlich der Impersonation Mechanismus nicht und der zu registrierende Plugin muss so eingestellt werden, dass er zum Beispiel mit den CRM-Administrator Credentials ausgeführt wird. Hier sollte man als Entwickler natürlich entsprechende Vorsicht und Sorgfalt walten lassen.

Fazit

Während der Laufzeit über das Erstellen einer Konfiguration Plugins zu registrieren kann eine sinnvolle Erweiterung für Dynamics CRM sein. Das Beispiel zeigt, wie einfach dies im Prinzip ist.
Unser Autonumber-Plugin werden wir in kürze über unseren Codeplex-Channel (https://www.codeplex.com/site/users/view/teamGreenIT) zur Verfügung stellen.


Schlagwörter: , ,


Diesen Blogeintrag bewerten:


Haben Sie Fragen zu diesem Artikel oder brauchen Sie Unterstützung?

Nehmen Sie mit uns Kontakt auf!

Wir unterstützen Sie gerne bei Ihren Vorhaben!


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Kontakt
Lassen Sie sich von uns beraten
Wir freuen uns über Ihr Interesse an unseren Leistungen. Hinterlassen Sie
uns Ihren Namen, Ihre Telefonnummer und E-Mail Adresse – wir melden
uns schnellstmöglich bei Ihnen.
Kontakt aufnehmen