čtvrtek 25. února 2010

Cachování edit metod

Na blogu Dynamics AX Daily jsem se dočetl, že v AX2009 je možné na formuláři cachovat i edit metody (link). Samozřejmě jsem si to hned otestoval a… opravdu to funguje! Tahle schopnost AX2009 mi byla do dneška utajena. Stejně jako v případě display metod musí být i edit metoda definována na tabulce a cachování se aktivuje pomocí cacheAddMethod() na datovém zdroji formuláře.

Serializace objektů - úvod

Úvod Serializace objektů je v Dynamics AX intenzivně využívaná, ale obvykle je tak dobře skrytá, že si ji mnoho vývojářů příliš neuvědomuje. Pochopení její implementace je ale v některých situacích nezbytné a v opačném případě vznikají zbytečné a často i poněkud záhadné chyby. Podívejme se na tedy serializaci trochu podrobněji. Co to je? Serializace objektu znamená uložení jeho stavu do podoby, kterou je možné uložit nebo někam přenést. Objekt je pak možné obnovit (deserializovat) do původního stavu. Jako příklad použití v Dynamics AX lze uvést:
  • Ukládání uživatelského nastavení (dříve použité hodnoty v dialogových oknech, vlastní nastavení formulářů apod.).
  • Ukládání objektů pro pozdější použití (úlohy spouštěné v určitém čase, uložení dotazu (např. pro Zabezpečení na úrovni záznamů))
  • Klient/server optimalizace (spuštění dialogu serverové třídy na klientu)
Realizace Cílem serializace je převést referenční datové typy (což jsou fakticky odkazy na místo v paměti) na hodnotové. A protože v Dynamics AX patří mezi hodnotové typy i kontejner, je pro účely serializace jasnou volbou. Příklad: Mějme třídu Class1, obsahující instanční proměnné str retezec1 a real cislo1 (ty představují stav objektu). Uložit stav tohoto objektu do kontejneru lze snadno pomocí speciální syntaxe pro vytváření kontejnerů: [retezec1, cislo1]. Takto jsme získali kontejner, obsahující string a real – všechno hodnotové typy. Tento kontejner může být přímo uložen do databáze, předán jako parametr metody mezi klientem a serverem a podobně. Deserializace objektu provedeme tak, že vytvoříme novou instanci Class1 a hodnoty jejích proměnných naplníme z kontejneru. Opět můžeme využít speciální syntaxe a provést přiřazení jako [retezec1, cislo1] = kontejner; Pokud přidáme nebo odebereme proměnnou, musíme změnit serializační i deserializační kód. K tomu, aby to nebylo nutné dělat ručně, se v Dynamics AX používají makra, což je pro řadu vývojářů asi nejobtížnější část problému. Makra jsou (zjednodušeně řečeno) speciální příkazy, které ovlivňují, jak se zdrojový kód zkompiluje. Lze například – v závislosti na hodnotě parametru – zkompilovat aplikaci jednou s ladícími příkazy a podruhé bez nich. V AX jsou uvozeny znakem # a nejčastěji se používají pro definici konstant, ale lze vytvářet i podmíněně kompilovaný kód, makra s parametry atd. Více na MSDN. Pro téma serializace stačí vědět, že kód definovaný pomocí klauzule #define, #localmacro apod. se před kompilací vloží na místo, kde je makro použito. Vytvoříme-li makro #define.CurrentList(retezec1, cislo1), můžeme kontejner s proměnnými vytvořit prostým voláním [#CurrentList] (protože to je pro kompilátor to samé jako [retezec1, cislo1]). Obdobně deserializaci zapíšeme jako [#CurrentList] = kontejner;. Příště se podíváme na verzování serializovaných objektů a některá konkrétní použití serializace v AX.

pátek 19. února 2010

Certifikace Trade & Logistics

Dnes jsem úspěšně složil certifikační zkoušku AX 2009: Trade & Logistics!

čtvrtek 11. února 2010

Enterprise Portal Development Cookbook

Na blogu EP teamu se nedávno objevila "kuchařka" pro vývoj Enterprise Portálu. Protože se EP vůbec nevěnuji, nejsem schopen zhodnotit její kvality. Ale nepochybuji, že se někomu bude hodit. Přímý odkaz zde.

úterý 9. února 2010

AX6: modely

Na konci minulého roku zveřejnil Michael Freurgaard Pontoppidan (mfp) několik příspěvků o nové funkci, chystané do Dynamics AX 6, zvané Modely (Models). Protože tyto modely významně ovlivní způsob nasazování AX aplikací, rozhodl jsem se sepsat stručné shrnutí v češtině. A protože nemám připravovanou verzi AX k dispozici, vypůjčil jsem si obrázky s Michaelovým svolením přímo z jeho blogu. Vezměte prosím na vědomí, že verze 6 je stále ve vývoji, a také že některé podstatné informace nebyly publikovány. Na definitivní podobu si prostě musíme ješte počkat. Co je to ten model? Model je určité seskupení aplikačních objektů uvnitř vrstvy a v jedné vrstvě jich může existovat libovolné množství. Model usnadňuje organizaci objektů a je ho možné exportovat, instalovat, odinstalovat atd. Protože AX verze 6 již nebude obsahovat AOD soubory, budou modely hlavním prostředkem distribuce zdrojového kódu. Práce s modely v prostředí AX velmi připomíná práci s vrstvami; mimo AX zajištuje vetšinu funkcí samostatná aplikace AxUtil. Model je implementován jako řízené sestavení (managed assembly). Vytvoření modelu Model je možné vytvořit pomocí příkazu:
AxUtil create /model:"My Model" /Layer:USR
Všimněte si, že model je vytvářen v konkrétní vrstvě. Bylo by také možné určit databázi, vůči které se příkaz provede. Výběr modelu Obdobně jako vrstvu lze učit také výchozí model. Model ale může být změněn, narozdíl od vrstvy, i za běhu aplikace. Zvolit lze samozřejmě jen model patřící do aktuální vrstvy. Aktivní model je zobrazen ve stavovém panelu (a je ho odtud možné i změnit). Vývoj v modelu Modifikace objektů v AOT jsou automaticky přiřazeny k právě aktivnímu modelu. V jakém modelu je modifikace umístěna lze zobrazit přímo v AOT (pro každý element je zobrazen pouze model z nejvyšší vrstvy): V kontextovém menu přibyde také možnost přesunout element do jiného modelu. Export Modely je možné exportovat do souboru, což umožnuje přenést jen část vrstvy, aniž by bylo nutné sáhnout po exportu do .xpo. Díky modelům lze také lépe členit vyvíjenou aplikaci nebo dokonce vyvíjet několik (dostatečně izolovaných) rešení v jednom AX prostředí. Export se provádí opět pomocí AxUtil:
AxUtil export /model:"My Model" /file:MyModel.axmodel
Velkou výhodou exportovaného modelu je manifest. Manifest je obsažen přímo v souboru s modelem a obsahuje informace jako je jméno modelu, jeho verze, zdrojová vrstva a podobně. Manifest lze zobrazit:
AxUtil list /model:"My Model"
a případně změnit:
AxUtil edit /model:"MyModel" /manifest:Version="2.0.0.0",Publisher="MFP",Description="My first model"
Exportovaný model lze také opatřit elektronickým podpisem. Podpis pak může využít například zákazník k ověření, zda nebyl soubor během přenosu mofikován. Import Modely uložené do souboru je pochopitelně možné importovat do AX:
AxUtil import /file:MyModel.axmodel
Do jedné vrstvy lze importovat více modelů, například řešení od dvou různých dodavatelů, což je dnes vcelku nepříjemný úkol (a noční můra při upgradech). Při takovém importu se mohou vyskytnout dva hlavní problémy:
  • Elementy mají stejné ID – MFP bez dalších podrobností tvrdí, že by tento problém měl být v AX 6 eliminován. Zatím je známo jen to, že rozsah ID bude řádově zvětšen.
  • Elementy mají stejný název (typicky: obě řešení mění nějaký standardní objekt) – tomu samozřejmě nelze zabránit (ačkoli často lze zásahy do standardního kódu minimalizovat vhodným návrhem aplikace). Vývojáři AX 6 chtějí snížit množství těchto konfliktů jemnějším členěním některých typů objektů (dnes je například „jednotkou modifikace“ celý objekt typu Menu a pokud dvě řešení přidají menu item do stejného menu, dojde ke konfliktu).
Importu lze říct, jak se má zachovat v případě, že narazí na konflikt. K dispozici jsou tyto tři možnosti:
  • Import modelu je zrušen.
  • Původní objekty jsou přepsány. Protože by následné odinstalování tohoto modelu mohlo zanechat aplikaci v nekonzistentím stavu, budou spolu s tímto modelem odinstalovány i modely, jejichž objekty byly importem přepsány.
  • Model je naimportován a konfliktní objekty jsou umístěny do nového modelu ve vyšší vrstvě (např. BUS→BUP), kde je možné konflikty vyřešit.
Mazání modelu K odebrání modelu opět poslouží AxUtil:
AxUtil delete /model:"My Model"
Závěr Mfp uvádí o něco více podrobností, takže v případě zájmu navštivte jeho blog. Nicméně dokud není AX 6 hotova, stejně není nic definivní. Až bude zveřejněna, určitě se na modely a jejich implementaci podívám podrobněji.

pátek 5. února 2010

Pole na dialogu

Někdy je potřeba umístit na dialog pole (tzn. datový typ s Array elementy). Zdrojový kód je triviální:
Dialog      dialog = new Dialog("Dimenze");
;
dialog.addField(typeId(Dimension));
dialog.run();
Pokud je dále třeba nastavit nějakou vlastnost, například AllowEdit, nabízel by se takovýto zápis:
Dialog      dialog = new Dialog("Dimenze");
DialogField field;
;

field = dialog.addField(typeId(Dimension));
field.allowEdit(false);

dialog.run();
Jenže… výsledek není správný. Znepřístupněné je jen první políčko: Na formuláři totiž ve skutečnosti vznikne více políček (Fld1_1, Fld1_2 a Fld1_3) a proměnná field ukazuje pouze na první z nich. Je nutné projít všechny všechná příslušná políčka a nastavit požadovanou vlastnost každému zvlášť.
Dialog                  dialog = new Dialog("Dimenze");
DialogField             field;
SysDictType             dictType;
FormBuildStringControl  control;
int i;
;

field = dialog.addField(typeId(Dimension));

dictType = new DictType(typeId(Dimension) >> 16);

for (i = 1; i <= dictType.arraySize(); i++)
{
   control = dialog.dialogForm().buildControl(field.fieldname(i));
   control.allowEdit(false);
}

dialog.run();
Výsledný dialog pak má všechny dimenze neaktivní, jak bylo požadováno.