Plug-in’ler hakkında temel bilgileri öğrendiğimize gore
artik plug-in yazabiliriz. Asagida vereceğim orneklerde bir plug-in içerisinde
yapabileceğiniz temel işlemleri anlatmaya calisacagim. Bu kodlara CRM SDK\SampleCode\CS\Plug-ins
içerisinden ulaşabilirsiniz.
Veritabanina gitmeden kayitlari değiştirmek
Daha once de ifade ettiğim gibi CRM içerisinde bir kayit
veritabanina gitmeden Pre-Operation(Pre-Event) adiminda kaydettiğiniz bir
plug-in ile kullanicinin oluşturmak istediği kayda ulaşabilirsiniz.
Asagidaki kod oluşturulan bir account(firma) nesnesinin
içerisine eger yok ise bir numara oluşturarak bunu accountnumber(müşteri
numarasi) alanina vermekte böylece kayitta olmayan bir alan veritabanina bu
alan eklenmiş bir sekilde gidecek.
Kodda da görebileceğiniz uzere ilk once Execute metodumuzu
oluşturuyoruz. Biliyorsunuz ki bu metod parametre olarak içine aldigi
ServiceProvider ile bize ihtiyacimiz olan butun verileri sunacak.
Ilk once Context’i ServiceProvider’dan türetiyoruz. Daha
sonra da Context içerisindeki Target’in bir Entity mi olup olmadigina
bakıyoruz. Tam bu noktada gelin Context nesnesinin içerisine bir bakalim.
Asagidaki ekran goruntusunu bu plug-in’i debug ettiğim anda
aldim. Ilerleyen bölümlerde bir plug-in’in nasil debug edileceğini anlatacagim.
Simdilik Context’e odaklanalim.
Gorebileceginiz uzere Context UserId, BusinessUnitId,
MessageName, PrimaryEntityName, CreatedOn gibi o anda isimize yarayacak birçok
veri yiginini içermekte. Iste Plug-in içerisinde ihtiyacimiz olanlari buradan
alip kullanacagiz.

Entity ise onu entity sinifindan bir nesne haline
getiriyoruz.
Bu sefer bu oluşturduğumuz yeni entity nesnesi account
turunden bir nesne midir diye bakıyoruz.
Daha sonra Icinde accountnumber diye bir alan var mi diye
bakıyoruz. Yoksa iste tam bu noktada veritabanina doğru yolculuğa cikmis olan
kullanicinin bu kaydına müdahale edip içerisine bizim urettigimiz numara ile
accountnumber nesnesini doldurarak entity mize veriyoruz. Artik içerisinde
accountnumber alani da var.
/// <summary>
/// A plug-in that auto generates an account number when an
/// account is created.
/// </summary>
/// <remarks>Register this plug-in on the Create message, account
entity,
/// and pre-operation stage.
/// </remarks>
//<snippetAccountNumberPlugin2>
public void Execute(IServiceProvider serviceProvider)
{
//
Obtain the execution context from the service provider.
Microsoft.Xrm.Sdk.IPluginExecutionContext context
= (Microsoft.Xrm.Sdk.IPluginExecutionContext)
serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
// The
InputParameters collection contains all the data passed in the message request.
if
(context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
//
Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
//</snippetAccountNumberPlugin2>
//
Verify that the target entity represents an account.
//
If not, this plug-in was not registered correctly.
if (entity.LogicalName == "account")
{
// An accountnumber attribute should not already exist
because
// it is system generated.
if (entity.Attributes.Contains("accountnumber")
== false)
{
// Create a new accountnumber attribute, set its value,
and add
// the attribute to the entity's attribute collection.
Random rndgen = new Random();
entity.Attributes.Add("accountnumber",
rndgen.Next().ToString());
}
else
{
// Throw an error, because account numbers must be system
generated.
// Throwing an InvalidPluginExecutionException will cause
the error message
// to be displayed in a dialog of the Web application.
throw new InvalidPluginExecutionException("The account number
can only be set by the system.");
}
}
}
}
Umarim birsey dikkatinizi çekmiştir. Entity içerisine direkt
alani Attributes.Add metodu ile ekliyoruz. Yani bir update işlemi yapmıyoruz
zaten kayit daha veritabanina gitmedi doğal olarak CRM Service nesnesinin bir
instance’ini olusturmamiza da gerek kalmadi.
Update aninda update edilmemiş değerlere ulaşmak
Baslik biraz karisik gelebilir ama aslinda tam olarak da
durum bu update aninda update edilmemiş alanlara ulaşmak istiyorsaniz birazdan
bahsedecegim yöntemi uygulamniz gerekmekte. Peki biz neye neden ulasamiyoruz
diye soracak olursaniz aciklayayim. Dynamics CRM’in Create aninda kayit ile
ilgili elde ettiği butun bilgileri bize Target’tan türettiğimiz entity
içerisinde verir. Asagidaki ekran goruntusunde de bu durumu görebilirsiniz.

Update aninda durum bundan farkli sistem bize sadece (doğal
olarak) update edilmiş alanlari vermektedir. Asagidaki ekran goruntusune
bakabilirsiniz.

Ben bu contact üzerinde sadece jobtitle alanini güncelledim.
Sistem jobtitle ve yaninda ihtiyaç duyulacak birkaç bilgiyi daha Target’a
vermekte o kadar.
Simdi konu basligina dönecek olursak iste tam bu update
aninda ben update edilmemiş bir alanin değerine ulaşmak istersem ne yaparim?
Sistemde bunun için Image yani o kaydin o anki snapshot’ini almamizi sağlayan
bir ozellik var.
Herhangi bir plug-in step’i üzerinde sag tuşa basarak “create
new image” seçeneğini seçtiğimizde asagidaki ekran karsimiza gelecektir.

Bu ekranda Pre ve Post olarak istediğimiz alanlari parametre
olarak seçebilir ve bunlara genel bir isim verebiliriz. Ben Target dedim.
Iste bu ayarlamayi yapdiginizda asagidaki ekran
goruntusundeki gibi update aninda değişmeyen ama sizin erişmek istediğiniz
alan/alanlar PreEntityImages içerisinde hazir olacaktır.

Peki kod tarafında buna nasil ulasacagiz derseniz o da su
sekilde olacak;
Once image nesnesine ulaşıyoruz:
Entity image = (Entity)context.PreEntityImages["Target"];
Sonra image içerisinden istediğimiz alana erişiyoruz:
String descriptionMessage = "Old
full name: " + image["fullname"];
Uzerinde calistigim nesnenin id’si nerede?
Update edilmis ya da
post-operation durumdaki bir nesnenin id’sine ihtiyaç duyarsaniz su sekilde
elde edebilirsiniz:
Guid id = new Guid(context.OutputParameters["id"].ToString());
Ya da
Guid id = context.PrimaryEntityId;
Plug-in’ler arasinda bilgi paylasimi
Eger bir plug-in içinde oluşturduğumuz
bir veriyi diğer plug-in’lerin de erişmesini istiyorsak “SharedVariables”
yapisini kullanmamiz gerekmekte. SharedVarabiles aslinda bir parametre
kolleksiyonu ve içerisinde paylaşmak istediğiniz nesneleri saklayabilirsiniz.
Asagida 2 tane plug-in
yer almakta. Ilk plug-in (PreEventPlugin)
context.SharedVariables.Add("PrimaryContact", (Object)contact.ToString());
Kodu ile Contact isimli Guid nesnesini “PrimaryContact” adinda SharedVariables içerisinde
saklamakta.
Ikinci plug-in ise
Post-event aninda calismakta ve SharedVariables’den istediği değeri örnekteki gibi
almaktadır.
Boylece plug-inler arasi
veri transferi ve yapilmis olmakta.
Guid contact = new Guid((string)context.SharedVariables["PrimaryContact"]);
public class PreEventPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
//
Obtain the execution context from the service provider.
Microsoft.Xrm.Sdk.IPluginExecutionContext context
= (Microsoft.Xrm.Sdk.IPluginExecutionContext)
serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
//
Create or retrieve some data that will be needed by the post event
//
plug-in. You could run a query, create an entity, or perform a calculation.
//In
this sample, the data to be passed to the post plug-in is
//
represented by a GUID.
Guid contact = new Guid("{74882D5C-381A-4863-A5B9-B8604615C2D0}");
// Pass
the data to the post event plug-in in an execution context shared
//
variable named PrimaryContact.
context.SharedVariables.Add("PrimaryContact",
(Object)contact.ToString());
}
}
public class PostEventPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
//
Obtain the execution context from the service provider.
Microsoft.Xrm.Sdk.IPluginExecutionContext context
= (Microsoft.Xrm.Sdk.IPluginExecutionContext)
serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
//
Obtain the contact from the execution context shared variables.
if (context.SharedVariables.Contains("PrimaryContact"))
{
Guid contact =
new Guid((string)context.SharedVariables["PrimaryContact"]);
//
Do something with the contact.
}
}
}