Dynamics AX 2012'de Hangi Alt Sınıfın Örneklendirileceğini Bulmak İçin SysExtension Çerçevesini Kullanma
Yayınlandı: 16 Şubat 2025 00:26:02 UTC
Son güncelleme: 12 Ocak 2026 08:43:21 UTC
Bu makale, Dynamics AX 2012 ve Dynamics 365 for Operations'ta az bilinen SysExtension çerçevesinin nasıl kullanılacağını ve öznitelik süslemelerine dayalı alt sınıfların nasıl örneklendirileceğini, böylece işleme sınıfı hiyerarşisinin kolayca genişletilebilir bir tasarımına nasıl olanak tanınacağını açıklamaktadır.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Bu yazıda yer alan bilgiler Dynamics AX 2012 R3'e dayanmaktadır. Diğer sürümler için geçerli olabilir veya olmayabilir. (Güncelleme: Bu makaledeki bilgilerin Dynamics 365 for Operations için de geçerli olduğunu doğrulayabilirim.)
Dynamics AX'te işlem sınıfları uygularken, genellikle her alt sınıfın bir enum değerine karşılık geldiği veya başka bir veri bağlantısına sahip olduğu bir sınıf hiyerarşisi oluşturmakla karşı karşıya kalırsınız. Klasik bir tasarım, üst sınıfta, girdiye bağlı olarak hangi sınıfın örneklendirileceğini belirleyen bir switch ifadesine sahip bir yapıcı yöntem bulundurmaktır.
Bu prensipte iyi çalışır, ancak çok sayıda farklı olası girdi varsa (bir enum'da birçok öğe veya girdi birkaç farklı değerin birleşimi olabilir), bakımı zahmetli ve hataya açık hale gelebilir ve tasarımın her zaman dezavantajı, yeni bir alt sınıf eklediğinizde veya hangi alt sınıfın hangi girdiye göre kullanılacağına dair değişiklikler yaptığınızda söz konusu yapıcı yöntemi değiştirmeniz gerekecek olmasıdır.
Neyse ki, bunu yapmanın çok daha zarif, ancak ne yazık ki çok daha az bilinen bir yolu var; o da SysExtension çerçevesinin kullanılmasıdır.
Bu çerçeve, alt sınıflarınızı süslemek için kullanabileceğiniz özelliklerden yararlanarak sistemin hangi alt sınıfın ne için kullanılacağını belirlemesini sağlar. Yine de bir yapıcı metoda ihtiyacınız olacak, ancak doğru yapıldığında, yeni alt sınıflar eklerken onu asla değiştirmeniz gerekmeyecektir.
Hayali bir örnek üzerinden ilerleyelim ve InventTrans tablosuna dayalı bir tür işlem yapan bir hiyerarşi uygulayacağınızı varsayalım. Hangi işlemin yapılacağı, kayıtların StatusReceipt ve StatusIssue durumlarına ve ayrıca kayıtların SalesLine, PurchLine ile ilişkili olup olmadığına bağlıdır. Şimdiden birçok farklı kombinasyonla karşı karşıyasınız.
Diyelim ki şu an için sadece birkaç kombinasyonu ele almanız gerektiğini biliyorsunuz, ancak zamanla giderek daha fazla kombinasyonu ele almanızın isteneceği de farkındasınız.
Şimdilik, işleri nispeten basitleştirelim ve sadece StatusIssue değeri ReservPhysical veya ReservOrdered olan SalesLine ile ilgili kayıtları ele almanız gerektiğini, diğer tüm kombinasyonların şimdilik göz ardı edilebileceğini varsayalım. Ancak daha sonra bunları da ele almanız gerekeceğini bildiğiniz için, kodunuzu kolayca genişletilebilir şekilde tasarlamak isteyeceksiniz.
Şu anki hiyerarşiniz şöyle görünebilir:
- MyProcessorMyProcessor_SalesMyProcessor_Sales_ReservOrderedMyProcessor_Sales_ReservPhysical
Şimdi, üst sınıfta ModuleInventPurchSales ve StatusIssue enum'larına dayalı bir alt sınıfı örnekleyen bir metot kolayca uygulayabilirsiniz. Ancak bu durumda, her alt sınıf eklediğinizde üst sınıfı değiştirmeniz gerekecek ve bu, nesne yönelimli programlamada kalıtımın temel fikrine pek uymuyor. Sonuçta, her yeni toplu iş eklediğinizde RunBaseBatch veya SysOperationServiceBase'i değiştirmeniz gerekmiyor.
Bunun yerine, SysExtension çerçevesini kullanabilirsiniz. Bu, SysAttribute'ı genişleten başka bir sınıf eklemenizi gerektirecektir. Bu sınıf, işlem sınıflarınızı süsleyebileceğiniz özellik olarak kullanılacaktır.
Bu sınıf, SysOperation uygulamasında veri sözleşmesi sınıfı oluşturmaya çok benzer; çünkü bazı veri üyelerine ve bu değerleri almak ve ayarlamak için parametre yöntemlerine sahip olacaktır.
Bizim durumumuzda, Sınıf Bildirimi şu şekilde görünebilir:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Tüm veri üyelerini oluşturmak için bir new() metodu oluşturmanız gerekiyor. Dilerseniz bazılarına veya tümüne varsayılan değerler verebilirsiniz, ancak ben bunu yapmadım.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Ayrıca her veri üyesi için bir `parm` metodu da uygulamanız gerekiyor, ancak bunu nasıl yapacağınızı bildiğinizden emin olduğum için burada bunları atladım - aksi takdirde, bunu bir alıştırma olarak kabul edelim ;-)
Artık öznitelik sınıfınızı kullanarak her bir işlem sınıfınızı süsleyebilirsiniz. Örneğin, sınıf bildirimleri şöyle görünebilir:
StatusIssue::None,
StatusReceipt::None)]
class MyProcessor_Sales extends MyProcessor
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservOrdered,
StatusReceipt::None)]
class MyProcessor_Sales_ReservOrdered extends MyProcessor_Sales
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservPhysical,
StatusReceipt::None)]
class MyProcessor_Sales_ReservPhysical extends MyProcessor_Sales
{
}
Sınıflarınıza elbette istediğiniz gibi isim verebilirsiniz, burada önemli olan, sınıflarınızı yaptıkları işleme türüne karşılık gelen özelliklerle donatmanızdır. (Ancak Dynamics AX'te sınıf hiyerarşileri için isimlendirme kuralları olduğunu ve mümkünse bunlara uymanın her zaman iyi bir fikir olduğunu unutmayın).
Artık her bir sınıfın ne tür bir işlem yaptığını belirlemek için sınıflarınızı süslediğinize göre, gerektiğinde alt sınıfların nesnelerini oluşturmak için SysExtension çerçevesinden yararlanabilirsiniz.
Üst sınıfınızda (MyProcessor), aşağıdaki gibi bir yapıcı metot ekleyebilirsiniz:
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
MyProcessor ret;
MyProcessorSystemAttribute attribute;
;
attribute = new MyProcessorSystemAttribute( _module,
_statusIssue,
_statusReceipt);
ret = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(MyProcessor), attribute);
if (!ret)
{
// no class found
// here you could throw an error, instantiate a default
// processor instead, or just do nothing, up to you
}
return ret;
}
Asıl ilginç kısım - ve bu yazının asıl amacı (kelime oyununa bakmayın) - SysExtensionAppClassFactory sınıfındaki getClassFromSysAttribute() metodudur. Bu metot, bir hiyerarşinin üst sınıfının adını (ve bu üst sınıfın hiyerarşinin en üstünde olması gerekmez; sadece bu sınıfı genişleten sınıfların uygun olacağı anlamına gelir) ve bir öznitelik nesnesini kabul eder.
Ardından, belirtilen üst sınıfı genişleten ve ilgili bir öznitelikle donatılmış bir sınıf nesnesi döndürür.
Yapıcı metoda elbette istediğiniz kadar ek doğrulama veya mantık ekleyebilirsiniz, ancak burada önemli olan nokta, bir kez uygulandıktan sonra bu metodu bir daha asla değiştirmeniz gerekmemesidir. Hiyerarşiye alt sınıflar ekleyebilirsiniz ve bunları uygun şekilde süslediğinizden emin olduğunuz sürece, yapıcı metot yazıldığı sırada mevcut olmasalar bile onları bulacaktır.
Peki ya performans? Dürüst olmak gerekirse, performans testi yapmaya çalışmadım, ancak içgüdüsel olarak bunun klasik switch ifadesi tasarımından daha kötü performans göstereceğini düşünüyorum. Bununla birlikte, Dynamics AX'teki performans sorunlarının büyük çoğunluğunun veritabanı erişiminden kaynaklandığını göz önünde bulundurursak, bu konuda çok fazla endişelenmenize gerek yok.
Elbette, binlerce nesnenin hızlı bir şekilde oluşturulmasını gerektiren bir şey uyguluyorsanız, daha fazla araştırma yapmak isteyebilirsiniz, ancak uzun süren bir işlem için tek bir nesne örneği oluşturduğunuz klasik durumlarda bunun önemli olacağını sanmıyorum. Ayrıca, sorun giderme ipucumu (bir sonraki paragraf) dikkate alırsak, SysExtension çerçevesinin önbelleğe almaya dayandığı anlaşılıyor, bu nedenle çalışan bir sistemde önemli bir performans düşüşü olacağını sanmıyorum.
Sorun Giderme: Eğer yapıcı yöntem, alt sınıflarınızı doğru şekilde dekore ettiğinizden emin olmanıza rağmen bulamıyorsa, bu bir önbellekleme sorunu olabilir. Hem istemci hem de sunucudaki önbellekleri temizlemeyi deneyin. AOS'u yeniden başlatmanız gerekmeyebilir, ancak son çare olarak düşünülebilir.
Daha Fazla Okuma
Bu yazıyı beğendiyseniz, şu öneriler de ilginizi çekebilir:
- Dynamics AX 2012'de Makro ve strFmt ile Dize Biçimlendirme
- Dynamics AX 2012'de AIF Hizmeti için Belge Sınıfını ve Sorguyu Tanımlama
- Dynamics AX 2012'de data() ve buf2Buf() Arasındaki Fark
