Miklix

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

Bu makalede, Dynamics AX 2012 ve Dynamics 365 for Operations'taki az bilinen SysExtension çerçevesinin, öznitelik süslemelerine dayalı alt sınıfları örneklemek için nasıl kullanılacağı açıklanmakta ve böylece işleme sınıfı hiyerarşisinin kolayca genişletilebilir bir tasarımına olanak tanınmaktadır.


Bu sayfa, mümkün olduğunca çok kişi tarafından erişilebilir olması amacıyla İngilizce'den makine çevirisiyle çevrilmiştir. Ne yazık ki, makine çevirisi henüz mükemmelleştirilmiş bir teknoloji değildir, bu nedenle hatalar meydana gelebilir. Tercih ederseniz, orijinal İngilizce versiyonu buradan görüntüleyebilirsiniz:

Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012

Bu gönderideki 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şleme sınıflarını 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, daha sonra girişe göre hangi sınıfın örnekleştirileceğini belirleyen bir anahtara sahip olan üst sınıfta bir yapı yöntemine sahip olmaktır.

Bu prensipte iyi çalışır, ancak çok sayıda farklı olası girdiniz varsa (bir enumda çok sayıda öğe veya belki de girdi birkaç farklı değerin birleşimidir), bakımı sıkıcı ve hataya açık hale gelebilir ve tasarım her zaman, yeni bir alt sınıf eklediğinizde veya hangi alt sınıfın hangi girdiye göre kullanılacağı konusunda değişiklik yaptığınızda söz konusu yapı yöntemini değiştirmeniz gerekeceği dezavantajına sahiptir.

Neyse ki, bunu yapmanın çok daha zarif ama ne yazık ki çok daha az bilinen bir yolu var: SysExtension framework'ünü kullanmak.

Bu çerçeve, sistemin hangi alt sınıfın neyi işlemek için kullanılacağını anlayabilmesini sağlamak için alt sınıflarınızı süslemek için kullanabileceğiniz niteliklerden yararlanır. Yine de bir yapı yöntemine ihtiyacınız olacak, ancak doğru yapılırsa, yeni alt sınıflar eklerken bunu asla değiştirmeniz gerekmeyecek.

Hayali bir örneğe bakalım 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'sine ve kayıtların SalesLine, PurchLine veya hiçbiri ile ilişkili olup olmadığına bağlıdır. Şu anda, birçok farklı kombinasyona bakıyorsunuz.

O zaman diyelim ki şimdilik sadece birkaç kombinasyonu çözmeniz gerektiğini biliyorsunuz, ancak zamanla daha fazla kombinasyonu çözmeniz isteneceğini de biliyorsunuz.

Bunu nispeten basit tutalım ve şimdilik yalnızca ReservPhysical veya ReservOrdered StatusIssue değerine sahip SalesLine ile ilgili kayıtları işlemeniz gerektiğini, diğer tüm kombinasyonları şimdilik göz ardı edebileceğinizi, ancak daha sonra bunlarla ilgilenmeniz gerektiğini bildiğiniz için kodunuzu kolayca genişletilebilir olacak şekilde tasarlamak isteyeceğinizi varsayalım.

Şimdilik hiyerarşiniz aşağıdaki gibi görünebilir:

  • İşlemcim
    • İşlemcim_Satışlar
      • MyProcessor_Satış_RezervSipariş Edildi
      • İşlemcim_Satışlar_RezerviFiziksel

Şimdi, bir ModuleInventPurchSales ve bir StatusIssue enum'ına dayalı bir alt sınıfı örnekleyen bir yöntemi üst sınıfta kolayca uygulayabilirsiniz. Ancak daha sonra her alt sınıf eklediğinizde üst sınıfı değiştirmeniz gerekecektir ve bu, nesne yönelimli programlamada kalıtımın gerçek fikri değildir. Sonuçta, her yeni toplu iş eklediğinizde RunBaseBatch veya SysOperationServiceBase'i değiştirmeniz gerekmez.

Bunun yerine SysExtension framework'ünü kullanabilirsiniz. Bu, SysAttribute'u genişletmesi gereken başka bir sınıf eklemenizi gerektirecektir. Bu sınıf, işleme sınıflarınızı süsleyebileceğiniz nitelik olarak kullanılacaktır.

Bu sınıf, bir SysOperation uygulaması için bir veri sözleşmesi sınıfı oluşturma şeklinize çok benzer; çünkü bu sınıfta bazı veri üyeleri ve bu değerleri almak ve ayarlamak için parm yöntemleri bulunur.

Bizim durumumuzda ClassDeclaration aşağıdaki gibi görünebilir:

class MyProcessorSystemAttribute extends SysAttribute
{
    ModuleInventPurchSales  module;
    StatusIssue             statusIssue;
    StatusReceipt           statusReceipt
}

Tüm veri üyelerini örneklemek için bir new() metodu oluşturmanız gerekir. İsterseniz bazılarının veya hepsinin varsayılan değerlerini verebilirsiniz, ancak ben bunu yapmadım.

public void new(ModuleInventPurchSales  _module,
                StatusIssue             _statusIssue,
                StatusReceipt           _statusReceipt)
{
    ;

    super();

    module          = _module;
    statusIssue     = _statusIssue;
    statusReceipt   = _statusReceipt;
}

Ayrıca her veri üyesi için bir parm metodu da uygulamalısınız, ancak bunu nasıl yapacağınızı bildiğinizden emin olduğum için bunları burada atladım - aksi takdirde bunu bir egzersiz olarak düşünelim ;-)

Artık her bir işleme sınıfınızı süslemek için öznitelik sınıfınızı kullanabilirsiniz. Örneğin, sınıf bildirimleri şu şekilde görünebilir:

[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
                            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 istediğiniz ismi verebilirsiniz, burada önemli olan kısım, sınıflarınızı yaptıkları işleme karşılık gelen niteliklerle süslemenizdir. (Ancak Dynamics AX'te sınıf hiyerarşileri için isimlendirme kurallarının olduğunu ve mümkünse bunlara uymanın her zaman iyi bir fikir olduğunu unutmayın).

Artık sınıflarınızı her birinin ne tür işlem yaptığını belirleyecek şekilde dekore ettiğinize göre, alt sınıfların nesnelerini gerektiği gibi örneklemek için SysExtension çerçevesinden yararlanabilirsiniz.

Üst sınıfınıza (MyProcessor) şu şekilde bir yapı metodu ekleyebilirsiniz:

public static MyProcessor construct(ModuleInventPurchSales _module,
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;
}

Gerçekten ilginç olan kısım - ve bu gönderinin tamamının nesnesi (kelime oyununu mazur görün) - SysExtensionAppClassFactory sınıfındaki getClassFromSysAttribute() yöntemidir. Bu yöntemin yaptığı şey, 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; bu sadece bu sınıfı genişleten sınıfların uygun olacağı anlamına gelir) ve bir nitelik nesnesini kabul etmesidir.

Daha sonra belirtilen üst sınıfı genişleten ve karşılık gelen bir öznitelikle donatılan bir sınıf nesnesi döndürür.

Elbette yapı yöntemine istediğiniz kadar ek doğrulama veya mantık ekleyebilirsiniz, ancak buradaki önemli çıkarım, bir kez uygulandığında bu yöntemi bir daha asla değiştirmek zorunda kalmamanız gerektiğidir. Hiyerarşiye alt sınıflar ekleyebilirsiniz ve bunları uygun şekilde dekore ettiğinizden emin olduğunuz sürece, yapı yöntemi yazıldığı sırada mevcut olmasalar bile bunları bulacaktır.

Performans ne olacak? Dürüst olmak gerekirse kıyaslama yapmaya çalışmadım ama içgüdüsel hissim bunun muhtemelen klasik switch ifadesi tasarımından daha kötü performans gösterdiği yönünde. Ancak Dynamics AX'teki performans sorunlarının büyük çoğunluğunun veritabanı erişiminden kaynaklandığını düşünürsek, bu konuda çok fazla endişelenmezdim.

Elbette, binlerce nesnenin hızla oluşturulmasını gerektirecek bir şey uyguluyorsanız, daha fazla araştırma yapmak isteyebilirsiniz, ancak uzun bir işlem yapmak için yalnızca tek bir nesneyi örneklediğiniz klasik durumlarda, bunun önemli olacağından şüpheliyim. Ayrıca, sorun giderme ipucumu (sonraki paragraf) göz önünde bulundurarak, SysExtension çerçevesinin önbelleğe almaya dayandığı anlaşılıyor, bu nedenle çalışan bir sistemde önemli bir performans düşüşü olacağından şüpheliyim. Sorun giderme: Yapı yöntemi, doğru şekilde dekore edildiklerinden emin olmanıza rağmen alt sınıflarınızı bulamazsa, bu bir önbellek sorunu olabilir. Hem istemcide hem de sunucuda önbellekleri temizlemeyi deneyin. AOS'yi gerçekten yeniden başlatmanız gerekmemeli, ancak son çare olabilir.

Bluesky'de paylaşFacebook'ta paylaşLinkedIn'de paylaşTumblr'da paylaşX'te paylaşLinkedIn'de paylaşPinterest'e Pinleyin

Mikkel Bang Christensen

Yazar Hakkında

Mikkel Bang Christensen
Mikkel miklix.com'un yaratıcısı ve sahibidir. Profesyonel bilgisayar programcısı/yazılım geliştiricisi olarak 20 yılı aşkın deneyime sahiptir ve şu anda büyük bir Avrupa BT şirketinde tam zamanlı olarak çalışmaktadır. Blog yazmadığı zamanlarda, boş zamanlarını çok çeşitli ilgi alanları, hobiler ve aktivitelerle geçirmektedir ve bu da bir dereceye kadar bu web sitesinde kapsanan konuların çeşitliliğine yansıyabilir.