मुझे यहाँ एक मज़ा आया है। मैं एक गाइड पैरामीटर के साथ एक विधि बुला रहा हूं और कहीं कॉल के आमंत्रण और बुलाए गए विधि में पहला कदम के बीच, कहा गया है कि गाइड पैरामीटर बदला जा रहा है।

और इससे पहले कि कोई कोड नमूना मांगे, यह WAY इतना जटिल है कि एक साधारण संस्करण करने की कोशिश नहीं की जा सकती - आप क्यों पूछते हैं? सरल, अगर यह फिर से बनाने के लिए एक साधारण समस्या थी (और, हाँ, मैंने एक संपूर्ण समाधान बनाया है जिसमें केवल अलग-अलग स्थितियों को यथासंभव बारीकी से बनाया गया है, यह देखने के लिए कि क्या यह वास्तव में समस्या को फिर से बनाने में आसान है) , जो लोग संकलक लिखते हैं उन्होंने इसे उत्पादन में जाने से पहले ही ठीक कर दिया होगा। यह पर्यावरण की गहराई में है और मैं जानना चाहता हूं कि क्या किसी ने इसे पहले कभी देखा है और यदि हां, तो उन्होंने इसे कैसे देखा।

और यदि नहीं, तो माइक्रोसॉफ्ट कंपाइलर लोग इस पर एक नज़र डालना और इसे ठीक करना चाहेंगे, 'क्योंकि यह खराब है, वास्तव में खराब है।

यहाँ मुद्दा है: अगर मेरे पास इस तरह की एक विधि कॉल है:

Guid aGuid = Guid.NewGuid();
List<SomeClass> vList = _Handler.SomeMethodThatGeneratesTheList(aGuid)(*1);

और कहीं और कोड है (एक अलग परियोजना में जिसे Nuget के माध्यम से लाया गया था):

public List<SomeClass> SomeMethodThatGeneratesTheList(Guid aGuid)
(*2){
  // Do Some handling
}

जब कोड को बिंदु (* 1) पर लागू किया जाता है, तो guid पैरामीटर ठीक होता है। उस आह्वान और प्रवेश बिंदु (* 2) पर प्रवेश के बीच में कुछ भी नहीं के साथ (शाब्दिक रूप से विधि के प्रवेश बिंदु पर, अभी तक कोई प्रसंस्करण नहीं हुआ है, हम विधि की शुरुआत में हैं), पैरामीटर aGuid बदल गया है कुछ इस तरह से:

{c8f09e25-9779-431e-8086-a80400c13bec}

कुछ इस तरह के लिए:

{1518dcc0-0000-0000-0000-000000000000}

और अजीब तरह से पर्याप्त है, जैसे ही मैं परीक्षण को फिर से चलाता हूं, प्रतिस्थापित मूल्य बदल जाता है लेकिन जो एक वृद्धिशील फैशन प्रतीत होता है उदा।

{145de090-0000-0000-0000-000000000000}

केवल पहला खंड बदलता है, बाकी सभी शून्य रह जाते हैं।

वास्तविक NUnit इकाई परीक्षण कोड इस तरह दिखता है:

    [Test]
    public void TestHandleDbmetaDataDapperResultSet()
    {
        // Arrange

        // Act
        List<DbMetaDataTableOrView> vResult =
            _DbMetaDataContext
                .HandlerDbMetaDataTableOrViewInfo
                .FetchAllTableInfoAndTranslate
                    (_CodeGenParams.DatabaseInfoId);

        // Assert
        vResult.Should().NotBeNull();
    }

अद्यतन 2: इस संभावना को दूर करने के लिए अद्यतन कोड कि पैरामीटर मान की आपूर्ति करने वाली चीज़ किसी तरह से बंद हो जाती है, इस तरह दिखती है:

        [Test]
    public void TestHandleDbmetaDataDapperResultSet()
    {
        // Arrange
        Guid vTestParam = Guid.NewGuid();

        // Act
        //List<DbMetaDataTableOrView> vResult =
        //  _DbMetaDataContext
        //      .HandlerDbMetaDataTableOrViewInfo
        //      .FetchAllTableInfoAndTranslate(_CodeGenParams.DatabaseInfoId);
        List<DbMetaDataTableOrView> vResult =
            _DbMetaDataContext
                .HandlerDbMetaDataTableOrViewInfo
                .FetchAllTableInfoAndTranslate(vTestParam);

        // Assert
        vResult.Should().NotBeNull();
    }

प्रारंभिक मान: {c86c90ef-a284-470f-8949-36eacbd74afe} पैरामीटर जब यह कॉल कोड दर्ज करता है: {13a6d9d0-0000-0000-0000-0000-000000000000}।

यहां तक ​​​​कि उस लाइन को बदलना जो इस के लिए गाइड उत्पन्न करता है

            Guid vTestParam = Guid.Parse("c86c90ef-a284-470f-8949-36eacbd74afe");

इसे पहले रन पर उत्पन्न करता है: {1428e040-0000-0000-0000-000000000000} और यह दूसरे पर: {1457d9a0-0000-0000-0000-000000000000}

जहां _CodeGenParams.DatabaseInfoId में अपेक्षित गाइड मान है। बुलाए गए विधि का हस्ताक्षर बस है:

        public List<DbMetaDataTableOrView> FetchAllTableInfoAndTranslate
        (Guid aDatabaseId)

अद्यतन (प्रति अनुरोध, बुलाए गए विधि की पूरी सामग्री इस प्रकार आपूर्ति की जाती है :)

        public List<DbMetaDataTableOrView> FetchAllTableInfoAndTranslate
        (Guid aDatabaseId)
    {
        List<TableInfo> vTableList = FetchAllTableInfo(aDatabaseId);
        List<DbMetaDataTableOrView> vResult = new List<DbMetaDataTableOrView>();
        DbMetaDataTableOrView vDbTable;
        foreach (TableInfo vTable in vTableList)
        {
            vDbTable =
                vTable.DbMetaData.DeSerialize<DbMetaDataTableOrView>
                    (vTable.DbMetaDataDotNetType);
            vResult.Add(vDbTable);
        }
        return vResult;
    }

कोड दर्ज करते ही पहले ब्रेस पर ब्रेक पॉइंट लगाएं और पैरामीटर पहले ही बदल दिया गया है।

और संशोधन एकल-चरण के क्लिक पर होता है, जैसा कि मैंने पहले कहा था, शाब्दिक रूप से आह्वान और कोड में प्रवेश के बीच एक एकल चरण।

बाकी के कुछ विवरण:

लागू किया जा रहा तरीका एक अलग वर्ग में रहता है, एक अलग प्रोजेक्ट (.csproj) में लागू किया गया है जिसे एक nuget पैकेज के रूप में संग्रहीत किया गया है। यहां सभी गैजेट वर्तमान हैं: वीएस 2017 एंटरप्राइज, वर्तमान nuget.exe, .NET फ्रेमवर्क 4.7।

कॉलिंग यूनिट टेस्ट ने परीक्षण के तहत परियोजना के संदर्भ के माध्यम से कॉल किए गए nuget को विरासत में मिला है, जिसने सामान्य (nuget) तरीके से nuget पैकेज प्राप्त किया है। पैकेज स्वयं इंटरफ़ेस के हिस्से के रूप में बुलाए गए वर्ग विधियों को उजागर करता है जैसे कि _DbMetaDataContext IDbMetaDataContext का कार्यान्वयन है और यह सभी पुश्तैनी वर्गों के लिए सच है। सभी विधियों को उनके संबंधित इंटरफेस के कार्यान्वयन के रूप में उजागर किया जाता है। यह सुनिश्चित करने के लिए किया जाता है कि DI वांछित के रूप में काम करता है और वर्तमान DI इंजन निनजेक्ट है। सभी DI-आधारित इकाई परीक्षण इस बिंदु तक ठीक काम करते हैं।

मैंने अभी तक इसे किसी अन्य डीआई लाइब्रेरी के साथ करने की कोशिश नहीं की है, मैंने इतने लंबे समय तक निनजेक्ट का उपयोग किया है जिसमें कोई समस्या नहीं है कि मैंने कभी किसी अन्य पुस्तकालय को देखने की जहमत नहीं उठाई। मैं अभी इसे कठिनाई के संभावित स्रोत के रूप में दूर करने जा रहा हूं। आगे SimpleInjector की जाँच करेंगे।

इसमें कुछ समय लगेगा क्योंकि ऊपर दिए गए तरीके काफी बड़ी खाद्य श्रृंखला के शीर्ष पर हैं क्योंकि वे अंतर्निहित पुस्तकालय कोड के लॉट का अंतिम परिणाम हैं (इसलिए आपूर्ति करने में असमर्थता इसे पुन: पेश करने का "सरल" तरीका)। परीक्षण के तहत विधि एकमात्र तरीका है जो कक्षा में विफल रहता है, कक्षा में अन्य सभी विधियां अपने यूनिट परीक्षणों को ठीक से पास करती हैं, हालांकि, उनमें से कोई भी पैरामीटर के रूप में ग्रिड नहीं लेता है। स्ट्रिंग पासिंग, आदि बस काम करता है। इससे मैं यह निष्कर्ष निकालता हूं कि यह वह वर्ग नहीं है जो एक समस्या है, न ही वंशानुक्रम श्रृंखला, न ही इंटरफेस का उपयोग जो समस्या है, यह केवल उस वातावरण में एक ग्रिड पैरामीटर का संचालन है जो समस्या है। हैंडलिंग क्या है, इसलिए मैं DI को चित्र से बाहर निकालने की कोशिश करने जा रहा हूं (एक साधारण कार्य नहीं) क्योंकि यह हो सकता है जिस तरह से निनजेक्ट इंटरफ़ेस और कंक्रीट के बीच बंधन करता है कक्षा। मेरे पास बहुत सी स्थिर विधियां हैं जो मेरे लिए बाध्यकारी श्रृंखला का प्रदर्शन करती हैं इसलिए जब मैं अंतिम गैजेट का उपयोग करना चाहता हूं तो मुझे अंततः सभी बाइंडिंग याद रखने की आवश्यकता नहीं होती है। उस पद्धति ने इस बिंदु तक ठीक काम किया है, बाध्यकारी कॉल का उपयोग करके यूनिट परीक्षण सभी डीआई वातावरण में काम करते हैं, यह केवल आखिरी सेट है जो इस व्यवहार को पेश कर रहा है।

जैसे ही मैं और सीखूंगा, मैं इसे संपादित कर दूंगा। विधि दर्ज होने पर कॉल स्टैक यहां दिया गया है:

enter image description here

-3
Fred 7 अक्टूबर 2017, 23:47

2 जवाब

सबसे बढ़िया उत्तर

सबसे अजीब चीज जो मैंने कभी देखी है। पैरामीटर प्रकार को मानक "Guid aParam" से "Ref Guid aParam" में बदलें और यह अभी ठीक काम करता है।

अद्यतन: झूठी सफलता। ऐसा लगता है कि यह इस बात पर भी निर्भर करता है कि आपने अपने सिस्टम को कब रिबूट किया है। मैं अभी भी समस्या उत्पन्न करने में सक्षम हूं और, आगे की जांच के बाद, यह निष्कर्ष निकाला है कि यह एक डीबगर/रीशेर्पर मुद्दा हो सकता है जिसमें अब मैं एक ही समस्या को दोहराने वाले सरल कोड का उपयोग करके एक केस बना सकता हूं। एक बार केवल एक अलग समाधान बनाने की आवश्यकता है, एक वर्ग के साथ एक पैकेज जोड़ें जो एक इंटरफ़ेस लागू करता है, किसी अन्य सरल वर्ग से एक अलग इंटरफ़ेस जोड़ें, पूरी चीज़ को एक NuGet पैकेज में बदल दें, दूसरा समाधान बनाएं, एक साधारण वर्ग बनाएं जो उपयोग करता है NuGet पैकेज में क्लास का उदाहरण और सिंगल स्टेपिंग शुरू करें। वहां विफल रहता है, या कम से कम डिबगर कोड के माध्यम से कदम रखते समय सही मान दिखाने में विफल रहता है।

0
Fred 23 अक्टूबर 2017, 02:36

यह अनुकूलित कोड के साथ डीबगर समस्या होने की बहुत अधिक संभावना है। मुझे ठीक उसी घटना का सामना करना पड़ा (यहां तक ​​​​कि GUID के लिए समान संख्या पैटर्न) और अपना सिर खुजलाने और कुछ घंटों के लिए कोड को घूरने के बाद, मैंने पाया कि मेरे पास कोड ऑप्टिमाइज़ेशन सक्षम था। मैंने इसे अक्षम करने के बाद, सब कुछ अपेक्षित व्यवहार किया।

मेरे विशेष मामले में, मैंने डिस्सेप्लर कोड को देखा और पाया कि कॉल किए गए विधि के स्टैक फ्रेम पर GUID खोजने के बजाय, GUID को कॉलर विधि के स्टैक फ्रेम (SBP-xx के बजाय SBP+xx से लिया गया था। , वह विशेष अनुकूलन था)। डीबगर ने हालांकि वर्तमान स्टैक फ्रेम के भीतर इसके मूल्य की खोज की और इसलिए अजीब मान प्रदर्शित किए।

0
Turysaz 4 जिंदा 2019, 10:10