Dynamics CRM 2015 Plug-in Mimarisi



Benzer belgeler
ASP.NET CLASS KULLANARAK VERİTABANI İŞLEMLERİ


Samsun Çocuk Hizmetleri İ l Koordinasyon Sekretarya Birimi

Turquaz Windows kurulum dökümanı. ftp://ftp.mirror.ac.uk/sites/ftp.postgresql.org/binary/v7.3.1/windows/pgsql731wina1.exe

Ders Tanıtım Sunumu. Database Managegement II. Elbistan Meslek Yüksek Okulu Güz Yarıyılı. Öğr. Gör. Murat KEÇECĠOĞLU

Kaynak Kodlardan Derleme. Turquaz Muhasebe. Versiyon 0.2. Hüseyin Ergün. 26 Mart 2005

SQL Server 2008 kurulum için Microsoft Windows Installer 4.5 ve üzeri bileşenin bilgisayarınızda kurulu olması gerekir. İndirmek için tıklayın

WEB E-POSTA AYARLARI. Outlook 2003 Ayarı ( Resimli Anlatım )

MAT213 BİLGİSAYAR PROGRAMLAMA I DERSİ Ders 1: Programlamaya Giriş

NPratik Yazılım Kurulum Kılavuzu. Yedekleme İşlemi

AKINSOFT OfficeMessenger

İMAGE (SİSTEM GÖRÜNTÜSÜ) ALMA VE YÜKLEME NASIL YAPILIR. İmage nedir?

Android Ders Notları

BEUN VPN Hizmeti. VPN Nedir?

BİL BİLGİSAYAR PROGRAMLAMA (JAVA)

Flow Kullanım Klavuzu Mart 2014

Almanya Mail Hesabı ile Outlook Kurulumu

T.C. istanbul ÜNiVERSiTESi ÖĞRENCi BiLGi SiSTEMi. ÖĞRETiM ELEMANI KULLANIM KILAVUZU

C# ile e-posta Göndermek

GOOGLE DRİVE KULLANARAK FORM OLUŞTURMA

Nevşehir Hacı Bektaş Veli Üniversitesi. Moodle Uzaktan Eğitim Sistemi. Öğretim Elemanı Bilgilendirme Kılavuzu

Ecza Depolarına Ait E-Fatura Aktarım Modülü

ZİRVEDRİVE IOS YAZILIMI KULLANIM KILAVUZU

BU CİHAZ BİLGİSAYAR BAĞLANTILI SİSTEM OLMAYIP, BAĞLI OLDUĞU BİLGİSAYAR İLE DEVAMLI İLETİŞİM YAPMAMAKTADIR. Mali Onaylı Yazarkasa

SQL SERVER 2005 ENTEGRE SQL (VTY) VERİ TABANI YÖNETİM KURULUMU RESİMLİ ANLATIMI. Entegre SQL kurmadan önce SQLSERVER 2005,i kuralım öncelikle.

ZİRVEDRİVEWEB YAZILIMI KULLANIM KILAVUZU

Virtualmin'e Yeni Web Sitesi Host Etmek - Domain Eklemek

AKINSOFT. Eofis NetworkAdmin. AKINSOFT EOfis NetworkAdmin Kurulumu Bilgi Notu. Doküman Versiyon : Tarih : Copyright 2008 AKINSOFT

e-imzatr Kurulum Klavuzu

BM-209 Nesne Yönelimli Programlama. Yrd. Doç. Dr. İbrahim Alper Doğru Gazi Üniversitesi Teknoloji Fakültesi Bilgisayar Mühendisliği Bölümü

1.adım : Sql serverda Stored procedure oluşturmamız gerekiyor. Şu adımları izliyoruz.

NicProxy Registrar AWBS Modül Kurulumu Versiyon 1.0

Campus Online. Güncelleme: Haziran 24, 2013

AutoCAD 2011 Kurulumu

Beyhan KARPUZ, Uzman Kütüphaneci Karadeniz Teknik Üniversitesi 2017

vsphere Client(viClient) ile ESXI Kontrolü

SGK Otomasyon Tanıtım ve Kullanım Kılavuzu

Ecat 8. Hakbim Bilgi İşlem A.Ş. Versiyon

Zoru Kolay Yapmak İçin...

LOG SHIPPING Yusuf KAHVECİ Senior Database

Data Structures Lab Güz

Security Configuration Wizard ile güvenliği artırmak

NicProxy Registrar WHMCS Modül Kurulumu Versiyon 1.0

Microsoft networkte, "Access Control" default olarak "Share-level access control" a ayarlı gelir:

U y g u l a m a A i l e s i (Abakus 360, T-Panel, T-CRM) Tarayıcı Ayarları. IPera İletişim Teknolojileri

UZAKTAN EĞİTİM YÖNETİM SİSTEMİ (MMYO)EĞİTMEN YARDIM KILAVUZU

Tarih: 2 Ağustos 2018 Son versiyon: 1.8. EndNote X9 Windows Multi/Site kurulum talimatları

Course Online. Güncelleme: Haziran 24, 2013

"SQL Server Management Studio" yazılımını yüklemek için alttaki resmi sitesinden 180 günlük deneme sürümünü indirebilirsiniz.

OTURUM AÇMA ADLARI. Tavsiye Edilen Önhazırlık Enterprise Manager'i kullanabilmek.

Windows Live ID ve parolanızı giriniz.

HESAP MAKİNASI YAPIMI

Microsoft Outlook 2003 Kurulumu

Bu makalede 2003 sunucu, Windows 2003 Server anlamına gelmektedir. Aşağıda yapılan işlemler 2003 R2 sunucu üzerinde denenmiş ve çalıştırılmıştır.

Murat ÖZBEK

Resim 1. Access açılış sayfası. Resim 2. Access veri tabanı düzenleme sayfası

SIEMENS NX LİSANS İŞLEMLERİ

Microsoft FrontPage Web Sitesi Hazırlama. Ögr.Gör.N.Nilgün Çokça

V14xx Güncelleme İşlemleri

Automatically Upgrade (new) Client push installation Software update point installation Group Policy installation Logon script installation

Oluşturmak istediğimiz OU ye bir isim veriyoruz. Name kısmına ISTANBUL yazıyoruz,

Denetim Masası/Programlar/Windows özelliklerini Aç/Kapat

Yedek Nasıl Alınır? "Veri Tabanı Yedekleme ve Geri Alma" butonunu tıklayınca aşağıdaki gibi bir ekran açılacaktır.

NOT: VERİTABANINDAKİ TABLOLARI OLUŞTURMAYI DA UNUTMAYACAĞIZ.

1. VERİ TABANI ARAÇLARI

Outlook Web Access'a Güvensiz Girmeyin

Gerekli bağlantıları yapıp, ACS420 V3.03 programını çalıştırınız. Program açıldığında, LMS14 ün içindeki parametrelerin okunmasını bekleyiniz.

NJ-NJ ETHERNET/IP HABERLEŞMESİ

Toplu Kayıt Kullanıcı Kitapçığı

AEGEE-Eskişehir Online Web Yönetim Paneli ( WEBBY ) Yardım Dökümanı

Kullanım Kılavuzu

ASP.NET ile Bir Web Sitesi Oluşturma

1 Organizasyon Tanımlama

MOBİL UYGULAMA GELİŞTİRME

Tavsiye Edilen Önhazırlık Temel veritabanı kavramlar hakkında bilgi sahibi olmak. Hedefler Temel veritabanı güvenlik işlemlerini gerçekleştirebilmek

Flash ile Etkileşimli Öğretim Materyali Hazırlama Semineri

EKLEME SORGUSU. 2) ornekveritabani.accdb isimli veritabanınızı çift tıklayarak açınız. Sorarsa, İçeriği Etkinleştir komutunu uygulayınız.

Exchange Server 2010 Sertifika Oluşturma

ACS790 Programından OZW672 Web Server a tesis diyagramının aktarılması

EĞİTMENLER İÇİN UZAKTAN EĞİTİM SİSTEMİ (MOODLE) eders.giresun.edu.tr KULLANIM KILAVUZU

Liste Yükleme Ekranı Kullanım Kılavuzu

WINDOWS SERVER 2008 R2-SERVER 2012 DE IP SANALLAŞTIRMA

«BM364» Veritabanı Uygulamaları

1. Giriş HU-GO Web sayfası kullanıcı yüzeyinde kaydolma. Güverte Aracı (OBU) kayıt süreci. İçindekiler

VERİ ANALİZ KÜPLERİ. Küp Tasarım Formu (504200)

SQL Server 2014 Kurulum Adımları

2. Use Dns lookup, Use relay server aralarında seçim yapınız. Biz Dns lookup ile SMTP-mizi çalıştırdık. DNS lookup kısmında domain adınızı yazınız.

Outlook ve benzeri programların Ayarları

Hızlı Kurulum ve Yapılandırma Kılavuzu

Beyhan KARPUZ, Uzman Kütüphaneci Karadeniz Teknik Üniversitesi 2017

Subnet A da bulunan DHCP Server makinesinin ve client makinenin IP yapılandırması aşağıdaki gibidir.

Upgrading Internet Technology skills of Information and Communication Technologies (ICT) Professionals

AKINSOFT ProKuaför. Yardım Dosyası. Doküman Versiyon : Tarih : Sayfa-1. Copyright 2010 AKINSOFT

MEB E-Posta Hizmetleri ve Outlook Programı

AirTies Kablosuz Erişim Noktası (Access Point) olarak kullanacağınız cihazı bilgisayarınıza bağlayarak ayarlarını yapabilirsiniz.

Cost Modülü Ay sonu İşlemleri

AKINSOFT NetFoto. Yardım Dosyası. Doküman Versiyon : Tarih : Sayfa-1. Copyright 2010 AKINSOFT

e-imzatr Kurulum Klavuzu

ASTM (American Society for Testing and Materials)

Transkript:

Dynamics CRM 2015 Plug-in Mimarisi Baris KANLICA

Icerik Yazar Hakkinda... 2 E-Kitap Hakkinda... 2 Dynamics CRM 2015 Plug-in Mimarisi... 3 Plug-in Execution Context... 3 Organization Servise Erisme... 4 Notification Servise Erisme... 4 Input ve Output Parametreleri... 4 Pre ve Post Entity Imajlari... 5 Execute Metodu... 6 Plug-in ler Icerisindeki Hatalari Yakalamak... 7 Plug-in Yapici Metodlari... 10 Hadi Plug-in Yazalim... 11 Veritabanina gitmeden kayitlari değiştirmek... 11 Update aninda update edilmemiş değerlere ulaşmak... 13 Uzerinde calistigim nesnenin id si nerede?... 16 Plug-in ler arasinda bilgi paylasimi... 16 Plug-in Registration Tool u Kullanmak... 18 Plug-in i Debug Etmek... 24 Servis lere Attach olarak Debug Etme... 24 Plug-in Profiller i kullanarak Debug etme... 26

Yazar Hakkinda Yaklasik 15 yildir profesyonel olarak yazilim geliştirmekteyim. Bundan yaklasik 10 yil once Microsft Dynamics CRM 1.2 versiyonu ile tanistiktan sonra CRM yazilim danismani olarak yillardir Microsoft Dynamics CRM projeleri içerisinde cesitli pozisyonlarda görev aldim. Turkiye de CRM alaninda danismanlik yapan Omerd Business Solutions in kurucu ortagi olarak yillardir Yazilim Departman Mudur u unvanıyla bu sirkette görev yapmaktayım. 2 senedir de bu sirketin yurtdisi uzantisi olarak kurulan Mawens Business Solution da Genel Mudur u sifatiyla Londra da yasamaktayim ve CRM projeleri geliştirmeye burada devam etmekteyim. Bugune kadar 100 den fazla firmaya 150 den fazla CRM projesi geliştirdim ve bu alanda yaptigim calismalardan dolayi Microsoft tan 5 kere Dynamics CRM MVP odulunu ve unvanini aldim. Bilkom-Apple tarafından da Dijital Yasam Kocu unvanini almis bulunmaktayım. Turkiye de Edirne den Elazig a kadar ve yurtdisinda Londra da birçok universite, kurum ve etkinlikte konusmaci/egitmen olarak bulundum. Bircok sitede de editör ve yazar olarak yazilarim yayinlanmaktadir. Bana ulaşmak icin asagidaki kişisel bloğum olan www.cub-e.net i takip edebilir ve cub-e@cub-e.net adresine mail atabilirsiniz. E-Kitap Hakkinda Bu kitap Dynamics CRM alaninda yazilim yapan/yapmak isteyen herkese aciktir. Kodlar c# dilinde Visual Studio da yazilmis ve bunlar uzerinden anlatilmaktadir. Bu kitaptaki ornekleri yapabilmeniz icin 1. CRM 2015 2. CRM 2015 SDK 3. Visual Studio 2012-2013 Araclarina ihtiyaciniz bulunmaktadir. Bu e-kitap www.cub-e.net te Plug-in konusunu ele aldigim yazilarin biraraya toplanmis halidir. Ilereyen zamanlarda diger yazilarimi da 2015 versiyonuna guncelleyerek daha genis bir e-kitap olusturmayi amaclamaktayim. Umarim hepinize faydali olur.

Dynamics CRM 2015 Plug-in Mimarisi Sizlere bugun Dynamics CRM icerisindeki Plug-in Mimarisinden soz etmek isitiyorum. Plug-in ler IPlugin arayuzunden turetilmis kod parcaciklaridir ve CRM in icerisinde belli bir sira icerisinde calisirlar. Kabaca tariff edersek bunlar birer.dll dosyalaridir ve CRM e bu dosyaya ne zaman bakmasi gerektigini biz soyleriz. Plug-in ler olay bazli olarak calisirlar. Yani herhangi bir kayit olusturuldugunda, guncellendiginde, silindiginde vb.. olaylar oldukca biz ilgili ayari yapmissak calisirlar. Plug-in lerin en güzel yani pre ve post olarak calismaya ayarlanabilmeleridir. Plug-in ler olay bazli calisirlar demiştim iste bu olay olmadan önceki kaydin son hali üzerinden ve olay olduktan sonraki hali üzerinden işlem yapmaniza olanak sağlarlar. Plug-in lerin calismasi icin Microsoft.Xrm.Sdk.dll ve Microsoft.Crm.Sdk.Proxy.dll dosyalarinin referanslara eklenmis olmasi gerekmektedir. Tam yeri gelmisken bahsedeyim eger siz ucuncu parti bir.dll kullaniyorsaniz (yani kendi yazdiginiz siniflarin oldugu ya da diger uygulamalardan aldiginiz) bu.dll lerin ilgili serverin assembly klasöründe olduğundan emin olun yoksa plug-in calismayabilir. public class MyPlugin: IPlugin public void Execute(IServiceProvider serviceprovider) Detaya inecek olursak IPlugin arayuzunden turerilmis bir sinif içerisinde Execute metodu yer almalidir. Bu metod parametre olarak IServiceProvider arayuzunden türetilmiş bir bilgi yiginini içerir. Yani CRM kod içerisinde yapacagimiz işlemlerde bize CRM içerisinde olan olaylardan bize bilgi tasir ki biz de bu bilgileri kodun içerisinde kullanalim. Ne gibi veriler içinde tasimakta derseniz cok fazla detay verebilirim mesela su anda hangi kullanicinin işlem yaptigi, tasidigi nesnenin turunu, eger pre-plugin ise değerlerin değişmeden önceki halini vb bir cok veri içermekte. Simdi sirasiyla gelen veri yiginlarini inceleyelim. Plug-in Execution Context Calisma zamaninda oluşan veriler bu yapi içerisinde yer almaktadır. Bunlara kodun calisma hiyerarşisi ve entity bilgileri de dahildir. IPluginExecutionContext context = (IPluginExecutionContext) serviceprovider.getservice(typeof(ipluginexecutioncontext)); Bir olay olduğunda kayit edilmiş bir plug-in e bu veriler aktarılır aslinda o anda calisan butun plugin lere bu veriler aktarılır ama execution pipeline denen sralamaya uyarak aktarılır once pre sonra post pluginlere veri aktarılır. Hatta siz pre-plugin ile bir veriyi değiştirirseniz post-plugin e o veri aktarılır. Tabii burada yeri gelmişken bahsedeyim burada sozu edilen kodlarin sonsuz döngüye girmemeleri için sistem içerisinde Depth denen bir anahtar yer almaktadır. Varsayilanda bu bir plugin i arda arda 8 kere calistirir ve durdurur. Boylece sistemin bir kod yanlisigi ile çökmesi engellenmiştir. Bu değer değiştirebilir bir değerdir. Sistemin calismasi da aslinda su mantiga dayanmakta;

Yani Event Execution Pipeline a bir mesaj girdiginde Pre-Event -> Platform Islemleri (Yani CRM in kendi ic isleyisi) -> Post-Event seklinde islenmekte. Bu dongu senkron ve asenkron yapilar için böyle ilerlemekte. Organization Servise Erisme CRM içerisinde işlem yapabilmek her zaman bir servis nesnesine ihtiyaç duymaktayız. Iste kullanicinin hareketi neticesinde acilmiş bu servisi bize kullanmamiz için geçirmekte serviceprovider nesnesi. IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOr ganizationservicefactory)); IOrganizationService service = servicefactory.createorganizationservice(context.userid); Notification Servise Erisme Senkron olarak işaretlenmiş plug-in ler Microsoft Azure Service Bus a veri mesaj gondebilirler. IServiceEndpointNotificationService turunden olan bu bilgi Azure Service Bus a gönderilir. Bu sayede Azure Service Bus içerisinde endpoint oluşturulmuş ve endpoint i dinleyen 3. Parti bir servis ile iletişime geçebilmektedir. Input ve Output Parametreleri InputParameters nesnesi su anda yapilan hareketin yani su anda tetiklenmiş olayin bilgisini ve su anda üzerinde işlem görülen entity nin bilgisini içerir. Bu bilgiye erişmek için Target nesnesine

bakmamiz gerekmektedir ve bu nesneyi alip Entity class ina çevirebiliriz. Input nesneleri Request message yapisindadir. if (context.inputparameters.contains("target") && context.inputparameters["target"] is Entity) // Obtain the target entity from the input parameters. Entity entity = (Entity)context.InputParameters["Target"]; Fakat unutmaniz gereken bir nokta var her mesaj Entity nesnesini içermeyebilir. Ornegin DeleteRequest; Entity değil EntityReference dondurur. if (context.inputparameters.contains("target") && context.inputparameters["target"] is EntityReference) // Obtain the target entity from the input parameters. EntityReference entity = (EntityReference)context.InputParameters["Target"]; Benzer sekilde OutputParameters da Response message içerir. Ama sunu unutmayin ki senkron postevent ve asenkron plug-in ler OutputParameters turunden nesneler içerirler. Pre ve Post Entity Imajlari Bu konuyu okurken sakin Ingilizce Images kelimesinin resim anlamiyla karistirmayin buradaki anlami verinin o anki goruntusu seklinde ifade etmek daha doğru olur. Aslinda tam Ingilizce tabiriyle snapshot. PreEntityImages ve PostEntityImages verileri sistem tarafından size gönderilir ama siz ozellikle beklediğiniz alanlari plug-in in kayit işlemi sirasinda sisteme soyleyebilrsiniz. Burada tabii ki bir mantik çerçevesi olduğunu da unutmayin Create aninda bir nesnenin preimage i olamayacagi gibi Delete işleminden sonra da bir postimage beklemeyin. Simdi bu bilgileri verdikten sonra butun bunlari birleştirerek bir plug-in temel goruntusune bakalim. Aciklamalar kodun içinde. using System; using System.ServiceModel; using Microsoft.Xrm.Sdk; public class MyPlugin: IPlugin public void Execute(IServiceProvider serviceprovider) // Sandbox içerisinde calisan plug-in ler TracingService den yararlanabilirler. ITracingService tracingservice = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); //Context i elde ediyoruz. IPluginExecutionContext context = (IPluginExecutionContext) serviceprovider.getservice(typeof(ipluginexecutioncontext)); // InputParameters dan gelen verileri aliyoruz

if (context.inputparameters.contains("target") && context.inputparameters["target"] is Entity) // Target ile entity e erisiyoruz. Entity entity = (Entity)context.InputParameters["Target"]; // Beklediginiz entity geldi mi diye kontrol ediyoruz. if (entity.logicalname!= "account") return; // CRM Servisi elde ediyoruz IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFac tory)); IOrganizationService service = servicefactory.createorganizationservice(context.userid); try / Iste buradan sonrasi size kalmis istediğiniz kodu yazabilirsiniz. catch (FaultException<OrganizationServiceFault> ex) throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex); catch (Exception ex) tracingservice.trace("myplugin: 0", ex.tostring()); throw; Execute Metodu InputParameters ve Output Parameters konularindan bahsederken Request ve Response konularina değinmeden geçtim konu havada kalmasin diye ayri bir baslik altinda incelemenin daha doğru olacagini duşundum. CRM Servisi içerisindeki Execute Metodu Request ve Response yani Talep ve Yanit seklinde calismaktadir. Sistem üzerinde yapacaginiz butun hareketleri bu sekilde yaopabilirsiniz ki buna ayri metodlari bulunan Create, Update, Delete bile dahildir. Konu aslinda basit olduğundan çokça açıklanacak bir tarafi da yok gibi ama calisma yapisina bakacak olursak siz bir talepte bulunursunuz o da size yanit verir diye kisaca özetleyebiliriz.

Execute metodunun alabileceği Request lere makalenin sonunda yer vereceğim. Ama oncelikle sunu da belirteyim ki Request nesnesi opsiyonel parametrelere de sahiptir. Bu parametreler sunlardir. Parameter Description Messages SolutionUniqueName Islemin yapilacagi Cozumun Adi AddPrivilegesRoleRequest CreateRequest DeleteRequest MakeAvailableToOrganizationTemplateRequest SuppressDuplicateDetection Eslenen kayitlar bulunsun mu bulunmasin mi UpdateRequest CreateRequest UpdateRequest Kullanima dair ornek kod ise su sekilde; Account target = new Account(); target.name = "Fabrikam"; CreateRequest req = new CreateRequest(); req.target = target; req["suppressduplicatedetection"] = true; req["solutionuniquename"] = "MySolutionName"; CreateResponse response = (CreateResponse)_service.Execute(req); Eger isterseniz Execute Metodunu asenkron olarka da calistirabilirsiniz. Bu ekranda donmalari ve kullanicilarin ekrandan işlem bitmeden cikmalarini önleyecektir. Bunun için yapmaniz gereken ExecuteAsyncRequest mesajini geçmek olacaktır. ExecuteMultipleRequest ile de toplu daha aktarimlarinda kullanabileceğiniz mesajdir. xrm Mesajlarinin tamamina bu adresten ulaşabilirsiniz : https://msdn.microsoft.com/enus/library/gg334698.aspx CRM mesajlarina da bu adresten ulaşabilirsiniz : https://msdn.microsoft.com/enus/library/gg309482.aspx Plug-in ler Icerisindeki Hatalari Yakalamak Senkron calisan plug-in ler sandbox da olsun ya da olmasin herhangi bir hata ile karsilastiklarinda geriye kullaniciya uyari gösterecek bir yapiya sahiptirler ve bu durumu Dynamics CRM yönetir. Yani siz sadece hatayi geriye dondurursunuz.

Asenkron calisan yapilar için CRM içerisinde System Job(AsyncOperation) isimli bir bolum yer almaktadır. Iste asenkron hatalari da buradan takip edebilirsiniz. Senkron calisan plug-in lerde ise hata mesajlarini InvalidPluginException turunden bir hata göndererek kontrol edebilirsiniz. Message ozelligine herhangi bir değer gönderirseniz sistem onu gösterir aksi takdirde varsayilan hata mesaji görüntülenir. Ayrica sunu da belirteyim Sandbox içinde calismayan plug-in ler için hata mesajlari sistemin calistigi serverdaki Olay Goruntuleyici içerisinde Uygulama hatalari bolumu içerisine de kaydedilir. Plug-in içerisinde uygun gordugunuz yerde su sekilde hata fırlatabilirsiniz: throw new InvalidPluginExecutionException("The account number can only be set by the system."); Bir plug-in hata firlattiginda CRM su sekilde bir uyari vermektedir. Log dosyasini incelediğimizde de detaylari almaktayız. Bizim gönderdiğimiz mesaja dikkat edin lütfen; Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: The account number can only be set by the system. Detail: <OrganizationServiceFault xmlns="http://schemas.microsoft.com/xrm/2011/contracts" xmlns:i="http://www.w3.org/2001/xmlschema-instance"> <ErrorCode>-2147220970</ErrorCode> <ErrorDetails xmlns:a="http://schemas.datacontract.org/2004/07/system.collections.generic"> <KeyValuePairOfstringanyType> <a:key>callstack</a:key> <a:value i:type="b:string" xmlns:b="http://www.w3.org/2001/xmlschema"> at Microsoft.Crm.Sdk.Samples.AccountNumberPlugin.Execute(IServiceProvider serviceprovider) at PluginProfiler.Library.PluginAppDomainProxy.ExecuteCore(Stopwatch watch, ProfilerExecutionReport report, Object instance, Object executionparameter) at PluginProfiler.Library.AppDomainProxy.Execute(ProfilerExecutionConfiguration configuration, ProfilerExecutionReport report) </a:value> </KeyValuePairOfstringanyType> </ErrorDetails> <Message>The account number can only be set by the system.</message> <Timestamp>2015-04-08T15:29:50.7437667Z</Timestamp> <InnerFault i:nil="true" /> <TraceText i:nil="true" />

</OrganizationServiceFault> Ama siz temel bir hata yönetim sinifina sahip olmak ve yazdiginiz butun kodlarda kullanmak isterseniz su sekilde bir Exception mimarisini yazdiginiz kodda kullanabilirsiniz. Fakat burada unutmamaniz gereken nokta siz hata fırlatmaz hatalari kendiniz Handle ederseniz CRM kullaniciya hata mesaji göndermeyecektir. Bunun için InvalidPluginException i siz firlatmalisiniz. Asagidaki kodu Plug-in ler içerisinde kullanmanizi pek tavsiye etmem cunku sistem gayet detayli bir geri bildirim yapmakta ama bir hata aliyor ve isin içinden cikamiyorsaniz bu kodu denemenizde fayda olabilir. Hatayi serverda ya da CRM içinde bir yerlere yazdırıp incelebilrisiniz. Yine uygun gordugunuz bir yerde kullaniciya hata göstermek istiyorsaniz InvalidPluginExecutionException firlatmayi unutmayin. catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) Console.WriteLine("The application terminated with an error."); Console.WriteLine("Timestamp: 0", ex.detail.timestamp); Console.WriteLine("Code: 0", ex.detail.errorcode); Console.WriteLine("Message: 0", ex.detail.message); Console.WriteLine("Inner Fault: 0", null == ex.detail.innerfault? "No Inner Fault" : "Has Inner Fault"); catch (System.TimeoutException ex) Console.WriteLine("The application terminated with an error."); Console.WriteLine("Message: 0", ex.message); Console.WriteLine("Stack Trace: 0", ex.stacktrace); Console.WriteLine("Inner Fault: 0", null == ex.innerexception.message? "No Inner Fault" : ex.innerexception.message); catch (System.Exception ex) Console.WriteLine("The application terminated with an error."); Console.WriteLine(ex.Message); // Display the details of the inner exception. if (ex.innerexception!= null) Console.WriteLine(ex.InnerException.Message); FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.innerexception as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>; if (fe!= null) Console.WriteLine("Timestamp: 0", fe.detail.timestamp); Console.WriteLine("Code: 0", fe.detail.errorcode); Console.WriteLine("Message: 0", fe.detail.message); Console.WriteLine("Trace: 0", fe.detail.tracetext); Console.WriteLine("Inner Fault: 0", null == fe.detail.innerfault? "No Inner Fault" : "Has Inner Fault");

Plug-in Yapici Metodlari Bir plug-in için Microsoft Dynamics CRM de opsiyonel olarak kullanabileceğiniz yapici metod(constructor) türleri mevcuttur. Hic parametre vermeden yapici metod cagirabileceginiz gibi bir ya da iki parametre vererek de cagirabilirsiniz. SamplePlugin isimli plug-in için 3 cesit yapici metod ornegi asagidaki gibidir. public SamplePlugin() public SamplePlugin(string unsecure) public SamplePlugin(string unsecure, string secure) Yapici metodun ilk parametresi public yani unsecure bilgi yigini içermelidir. Ikinci parametre ise nonpublic (secure) bilgi yigini içermelidir. Buradan da anlayabileceğiniz uzere secure string encrypted yani sifrelenmis veri unsecure ise unencrypted yani sifrelenmemis değer içermelidir. Office Outlook client da calisan bir plug-in yazdiysaniz bilmelisiniz ki secure string offline yani cevrimdisi modda calismayacaktir. Bu bilgileri bir plug-in e Plugin Registration Tool vasitasiyla bir step in kaydi sirasinda sisteme iletiyoruz. Bu mesajlar için ayrilmis 2 alan bulanmaktadır. Step içerisinde bu ayarlamalari yaptıktan sonra yazmis olduğumuz degerlere kod içerisinden asagidaki gibi ulaşabilirsiniz. private readonly string _unsecurestring; private readonly string _securestring;

public AdvancedPlugin(string unsecurestring, string securestring) if (String.IsNullOrWhiteSpace(unsecureString) String.IsNullOrWhiteSpace(secureString)) throw new InvalidOperationException ("Unsecure and secure strings are required by the Advanced Plug-in, but not provided."); _unsecurestring = unsecurestring; _securestring = securestring; Hadi Plug-in Yazalim 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 plugin 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> false) // 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") == // 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.

Hangi Message da hangi image lara ualasabileceginizin listesi asagidaki gibidir. Mesaj Stage Pre-Image Post-Image Create PRE Hayir Hayir Create POST Evet Evet Update PRE Evet Hayir Update POST Evet Evet Delete PRE Evet Hayir Delete POST Evet Hayir 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.

Plug-in Registration Tool u Kullanmak Ilk plug-in imizi yazdıktan sonra geldi onu CRM içerisine eklemeye. Bu işlem için Plugin Registration Tool dediğimiz CRM SDK içerisinden cikan bir uygulamayi kullanacagiz. Bu uygulama sayesinde hem plug-in hem de custom workflow lari CRM içerisine ekleyebilmekteyiz. SDK\Tools\PluginRegistration\PluginRegistration.exe yolu ile ulaşabileceğiniz uygulamayi calistirdiginizda sizden bağlanmak istediğiniz server ile ilgili bilgileri isteyecektir. Dynamics CRM Online için Online i seçebilirsiniz ama unutmayin ki Office 365 hesabi kullaniyorsaniz Office 365 i seçmeniz gerekmekte. Ikisi de Online ama yetki mekanizmaları farkli. Eger On-Premises yani Microsoft disinda host edilen bir CRM e erişmek istiyorsaniz o zaman On- Premises seçeneğini seçmeniz gerekmekte. IFD ler için de bu seçeneği kullanabilirsiniz.

Eger Always display list of available orgs seçeneğiniz seçerseniz bağlanmak istediğiniz kullanici ile erişebileceğiniz organizasyonlarin listesini görüntüleyebilirsiniz. Basarili bir sekilde giriş yaptiginizda asagidaki gibi bir ekran karsiniza gelecektir. 1. Plug-in i sisteme kayit edebilmek için yukarıdaki Register düğmesine tikliyoruz ve ardindan Register New Assembly ye tikliyoruz.

2. Step#1 bolumundeki düğmesine tikliyarak kayit ettirmek istediğimiz.dll i seçiyoruz. 3. Step#2 bolumunde kaydetmek istediğimiz plug-in class ini seçiyoruz. 4. Step#3 bolumunde 2 tane seçeneğimiz bulunmakta; a. Sandbox : Bu seçeneği seçer isek plug-in bir Sandbox içerisinde calisacak yani dis ortamdan izole edilecek. Boylece bu plugin sistem içerisinde calisacak ama sisteme zarar veremeyecek ve izlenebilir olacak. Kisacasi yazdiginiz bir plug-in production ortamina tasimadan once test etmek için bu senecegi kullaniyoruz. b. None : hiçbir kisitlama olmadan.dll içerisindeki kodlar icra edilir. 5. Step#4 bolumunde ise plug-in nerede duracagini seçmemizi istemekte. a. Database: tavsiye edilen yöntem budur. Boylece dll işletim sistemi kaynakli sorunlardan izole edilir. Veritabani yedeklendikçe dll de içinde olduğundan yedeklenecektir ve herhangi bir durumda geriye dönmenizi sağlar.

b. Disk: Sistemin varsayilan dll yerleştirme yeri olan CRM Kurulum Yolu\\bin\assembly klasörü içerisinden dll i okur. Her bir server icin dll lerin belirtilen klasöre konmasi gerekmektedir. c. GAC: Global Assembly Cache üzerinden dll leri okur. Bu noktada bir not ileteyim eger server üzerinde calisan kodu debug etmek isterseniz yine server\bin\assembly klasörüne.pdb uzantili debug symbol lerinizi yerleştirmeniz gerekmekte. Ikinci bir not da eger serverda custom code execution kapaliysa açmak için server üzerinde powershell ile su kodlari calistirmaniz gerekmekte: Add-PSSnapin Microsoft.Crm.PowerShell $setting = get-crmsetting customcodesettings $setting.allowexternalcode="true" Degerleri kontrol etmek için bu komutlari calistirabilirsiniz : set-crmsetting $setting get-crmsetting customcodesettings Ayarlari tersine çevirmek için AllowExternalCode a False değerini vermeniz yeterli. Butun bu adimlari tamamladıktan sonra Register Selected Plugin düğmesine tikliyoruz. Plug-in kaydetmediki ilk adimi gerçekleştirmiş olduk sira diğer adimlarda :) Bu noktada plug-in i hangi event(ler) için yazdiysak onun için adim(lar) eklememiz gerekiyor. Plug-in anlatirken hep bir olay olduğunda yani veritabanina bir kayit eklendiğinde, silindiğinde ya da bir alani güncellendiğinde tetiklenebilir gibi orneklerle anlatıyoruz ama aslinda olay bundan daha derin gelin simdi custom entity ler için yani bizim oluşturduğunuz varliklar için sistem üzerinde nasil olaylarin tetiklenmelerini yakalayabiliyoruz. Literaturde bu konu message olarak geçmekte yani CRM eventlarina mesaj adi verilmekte. Message Name Ownership Type Message Availability Entity Supported Deployment Assign User-owned entities only Create User-owned and organizationowned entities Both Delete User-owned and organizationowned entities Both

GrantAccess User-owned entities only ModifyAccess User-owned entities only Retrieve User-owned and organizationowned entities Both RetrieveMultiple User-owned and organizationowned entities Both RetrievePrincipalAccess User-owned entities only Both RetrieveSharedPrincipalsAndAccess User-owned entities only Both RevokeAccess User-owned entities only SetState User-owned and organizationowned entities Both SetStateDynamicEntity User-owned and organizationowned entities Both Update User-owned and organizationowned entities Both Listede de yer aldigi gibi Retrieve, RetrieveMultiple yani veritababindna sorgulama ya da SetState yani bir kaydin durumun değişmesi gibi birçok farkli mesaj için plug-in i tetikletebilmekteyiz.

Lutfen sunu unutmayin yukarıdaki liste sadece custom entity ler için campaign, campaignactivity, list gibi entity ler için farkli mesajlar da mevcut tum listeye SDK içindeki Message-entity support for plug-ins.xlsx isimli dosyadan ulaşabilirsiniz. Simdi yeni bir adim ekleyerek bir mesaj için plug-in imizin tetiklenmesini saglayalim. Bunun için plugin üzerinde sag tuşa tıklayarak ya da yukarıdaki Register düğmesine tıklayarak acilan menüden Register New Step e tikliyoruz. Karsimiza asagidaki gibi bir pencere cikacak: Message: Yukarida bahsettigim mesajlardan birini buraya yazabilirsiniz. Hangi mesaji yazarsaniz plugin bu olay icin calisacak. Create/Update gibi mesaj isimleri yazarken otomatik olarak tamamlamaya calistigini göreceksiniz. Her bir mesaj icin ayri step ler tanimlaniz gerekmektedir. Primary Entity: Bu plug-in hangi entity yani varlik üzerinde calisacak. Buraya account, contact gibi bir varlik adi yazabilirsiniz. Secondary Entity: Bu plug-in i ikinci bir varlik icin tanıtacaksak buraya yazabiliriz. Event Pipeline Stage of Execution: Bu kisimda plug-in i pre yani veri veritabanina gitmeden mi calistiracagiz yoksa post yani kaydedildikten sonra mi calistiracagiz bunu seçiyoruz. Execution Mode: (sadece post da ikisinden birini seçebilmekteyiz) kod senkron yani sistemde kullanici ile etkileşimli ayni anda mi hareket etsin yoksa asenkron yani kullanicidan bagimsiz arka tarafta sessizce mi calissin bunu seciyoruz. Deployment: Bu kod server da mı calissin yoksa Outlook client gibi offline modda da calissin seçeneğidir. Bu yukarida acikladigim bolumler standart ayarlar. Yani her plug-in step i tanimladigimizda mutlaka bakmamiz gereken ayarlar. Ekranda bir de farkli ayarlar var onlara da bakalim. Event Handler: Bu kodun calismaya baslayacagi class in seçildiği yerdir. Cok değişik bir hareket yapmadiginiz surece zaten plugin registration tool otomatik bir sekilde Execute metodunu görecek ve orayi seçecektir. Name: Sistem bu step icin otomatik bir atamakta ama değiştirmek isterseniz buradan yapabilirsiniz.

Run in User s Context: Belki dokunmaniz gereken noktalardan biri olabilir. Bu kodu hangi kullanici yetkileriyle calistirmak istiyorsaniz onu seçebilirsiniz. Standartta ayari Calling User yani hangi kullanici bu işlemi yaparsa seçilidir. ExecutionOrder: eger ayni varlik içinde ve ayni mesaj icin başka bir plug-in daha varsa buraya sira numaralari vererek hangisini once-sonra calisacagini belirleyebilirsiniz. Unsecure ve Secure Configuration larin ne ise yaradigina zaten Plug-in Yapici Metodlari basligi altinda değinmiştim. Butun gerekli ayarlamalari yaptıktan sonra en allta bulunan Register New Step düğmesine tıklayarak işlemi tamamlıyoruz. Artik plug-in i test edebilirsiniz. Plug-in i Debug Etmek CRM 2015 icerisinde yazmis olduğumuz bir plug-in i debug etmenin iki temel yolu bulunmakta. Birinci yol calisan sisteme visual studio ile attach olarak yapilan, ikinci yol ise plug-in profiller kullanmak. Profiller icin Microsoft dokümantasyonlarda plug-in performansini ölçmek icin kullaniliyor dese de aslinda 1. Yöntemden daha saglikli olduğunu söyleyebilirim. Ozellikle Online sistemler icin başka çareniz de yok zaten. Servis lere Attach olarak Debug Etme Plug-in i sisteme kaydettikten sonra visual studio ile nereye attach olacagimizi seçmemiz gerekmekte. Kayit Ayari online offline asynchronous olarak kaydedilmis plugin ler (ya da custom workflow lar) sandbox (isolation mode) Servis w3wp.exe Microsoft.Crm.Application.Hoster.exe CrmAsyncService.exe Microsoft.Crm.Sandbox.WorkerProcess.exe Online : CRM Web arabirimini Offline : Outllok Client gibi offline yapidaki yazilimlar Kendimize uygun olan secimi yaptıktan sonra geriye bir tek breakpoint i seçip attach olmak kaliyor. Visual Studio yu acip Attach to Process.. diyoruz.

Sonra asagidaki ekran goruntusu gelecek ve ilgili servisi seçeceğiz. Asagidaki ekran goruntusunde de goruldugu uzere visual studio ilgili yerde devreye girecek ve bizim kodu debug etmemizi saglayacaktir.

Islem bu kadar basit sadece dikkat etmeniz gereken noktalar bulunmakta; 1. Eger disk e yaz adimini seçerek plug-in i sisteme kayit ettiyseniz bu plug-in in debug modda yeni bir versiyonunu ayni dizine kopyalamak icin plug-in üzerinde calistigi servisi yeniden baslatmaniz gerekir. 2. Plug-in üzerinde değişiklikler yaptiginizda her seferinde registration tool u ile güncelleme islemini yapin. 3. Eger plug-in i bu sekilde test edip butun işlemleri bitirdiyseniz onu veritabanina kaydetmenizi tavsiye ederim. Disk olarak birakmaniz pek önerilen bir yöntem değildir. 4. Her ne olursa olsun.pdb uzantili dosyalari assembly klasörü içerisinde birakmayin. 5. Sandbox içindeki bir plug-in i debug etmek istiyorsaniz asagidaki registery ayarinin 1 (DWORD) değeri tasidigindan emin olun : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\SandboxDebugPlugins Plug-in Profiller i kullanarak Debug etme Bu yöntemi kullanmak birçok bakimdan daha avantajli nedeni ise CRM size kullanicinin yaptigi hareketi simule ediyor ve böylece siz bunun üzerinden debug ediyorsunuz. Ayrica ciktilari baskalarina gönderme opsiyonu da bulunmakta. En değerli ozelligi ise plug-in i derleyip derleyip CRM e atmak gibi bir derdiniz yok. Yani bir hata mi yakaladiginiz ya da kodun bir yerini mi değiştirmek istiyorsunuz tek yapmaniz gereken degisikligi yapip uygulamaya yeniden bağlanmak ayni kullanici hareketi tekrar simule edilecek ve siz de yaptiginiz degisikligin etkilerini göreceksiniz. Simdi sirasiyla bu işlemi nasil yapacagimiza bakalim. Oncelikle Plug-in Registration Tool u aciyoruz ve işlem yapmak istediğimiz organizasyonu seçiyoruz. Tool üzerindeki Install Profiller düğmesine tikliyoruz. Boylece Plug-in Profiller da listemizde gozukmeye basliyor. Daha sonra test etmek istediğimiz step i seçiyoruz ve yine toolbar da yer alan Start Profilling düğmesine basıyoruz. Karsimiza asagidaki gibi Profiler Settings ekrani cikiyor.

Bu adimda iki secenekten birini seçmeniz lazim. Exception: Microsoft, Exception yöntemini önermekte gordugunuz gibi. Bunun anlami ise su kullanici ya da siz plug-in i tetikledeginizde plug-in calisacak ve sistem size bir hata mesaji gösterecek. Bu hata mesaji içerisinde plug-i debug etmemize yarayacak bilgiler yer alacak. Bu bilgileri almak icin cikan hata penceresinde Download Log File düğmesine basmaniz gerekmekte. Persist to Entity: Eger ikinci adimi seçerseniz bu sefer butun bilgiler CRM içerisinde bir Entity içerisine yazılacak. Iki adimdan birini seçip plug-in i tetikleyecek işlemi yaptıktan sonra Plug-in Registration Tool içerisinde Debug düğmesine tiklamaniz gerekmekte.

Karsiniza asagidaki gibi bir ekran gelecek. Bu ekran bir önceki seçtiğiniz adima gore iki işlemden birini yapmaniz gerekmekte; Eger Exception adimini seçtiyseniz ya basarak kaydetmiş olduğunuz hata dosyasinin yerini gösterin. Eger Persist To Entity adimini seçtiyseniz asagi doğru duran ok düğmesine basiniz. Karsiniza soyle bir ekran cikacak;

Bu ekrandan kaydettiğiniz profile log unu seçebilirsiniz. Sonra sirasiyla.dll dosyanizi sisteme gösterin ve debug etmek istediğiniz Plug-in i secin. Visual Studio yu acin ve PluginRegistration.exe uygulamasina attach olun. Start Execution dugmesina basin ve breakpoint koyduğunuz yerde bekleyin. Bir sure sonra Visual Studio a beklediğimiz yere gelecek ve bizim debug etmemizi sağlayacak.

Eger plug-in de değişiklik yapmaniz gerekiyorsa değişiklikleri yapin ama CRM e atmayin ilk once biraz önceki adimlari uygulayarak kodu tekrar test edin. Artik koddan eminseniz CRM içerisine gönderebilirsiniz güncellediğiniz.dll i. Bu arada belirtmeliyim ki asagida plug-in traces bolumunden de debug etmeden kodun nasil calistigini izleyebilirsiniz. Burada icin TracingService ile yazacaginiz mesajlar görüntülenecektir.